@@ -14,7 +14,8 @@ There are three ways to execute a query:
1414- ``Connection::prepare() `` passing SQL string (usually) containing placeholders to create an instance of
1515 ``PreparedStatement ``, then call ``PreparedStatement::execute() `` / ``PreparedStatement::executeParams() ``
1616 providing separate parameter values (this uses `pg_prepare() <http://php.net/manual/en/function.pg-prepare.php >`__
17- and `pg_execute() <http://php.net/manual/en/function.pg-execute.php >`__ internally)
17+ and `pg_execute() <http://php.net/manual/en/function.pg-execute.php >`__ internally). This way is described
18+ in :ref: `the next chapter <queries-prepared >`.
1819
1920All of the above methods return an instance of ``Result ``.
2021
@@ -33,7 +34,7 @@ this approach may lead to security issues if ``quote()`` is not applied thorough
3334It is only recommended to use ``Connection::execute() `` for queries that do not have parameters.
3435
3536On the other hand using ``prepare() `` / ``execute() `` workflow has an obvious
36- performance issue with single queries: it requires two round-trips to the database instead of one.
37+ performance issue with queries that are executed once : it requires two round-trips to the database instead of one.
3738
3839So ``prepare() `` / ``execute() `` are best used for queries that are executed multiple times with different parameters,
3940especially for complex ones where time spent on parsing / planning stage is substantial.
@@ -183,152 +184,3 @@ Methods that help with embedding stuff directly in SQL are also available, but t
183184``public function quoteIdentifier(string $identifier): string ``
184185 Quotes an identifier (e.g. table or column name) for inclusion in a query.
185186 It is a bad idea to take ``$identifier `` from user input even if using this method.
186-
187-
188- .. _queries-prepared :
189-
190- ``PreparedStatement `` API
191- =========================
192-
193- .. note ::
194- Instances of this class are created by ``Connection::prepare() `` method, ``PreparedStatement::__construct() ``
195- is marked internal and should not be used outside of ``Connection `` methods.
196-
197- The statement is automatically prepared when an instance of ``PreparedStatement `` is created and automatically
198- deallocated when the object is destroyed. Manual methods are also available just in case:
199-
200- ``public function prepare(): $this ``
201- Actually prepares the statement with `pg_prepare() <https://www.php.net/manual/en/function.pg-prepare.php >`__.
202-
203- ``public function deallocate(): $this ``
204- Manually deallocates the prepared statement using ``DEALLOCATE ... `` SQL statement.
205-
206- Trying to call ``execute() `` / ``executeParams() `` after ``deallocate() `` will result in an ``Exception ``.
207-
208- A very useful method allows specifying the number of parameters in the query:
209-
210- ``public function setNumberOfParameters(int $numberOfParameters): $this ``
211- Sets number of parameters used in the query.
212-
213- Parameter symbols should start with ``$1 `` and have no gaps in numbers, otherwise Postgres will throw an error,
214- so setting their number is sufficient.
215-
216- .. code-block :: php
217-
218- // If we know the number of parameters...
219- $prepared->setNumberOfParameters(2);
220- // ...then all the below methods will throw exceptions
221- $prepared->executeParams([1, 2, 3]);
222- $prepared->bindValue(4, 'foo');
223- $prepared->setParameterType(5, 'integer');
224-
225- .. tip ::
226- Number of parameters will always be set to a correct value by ``fetchParameterTypes() ``, so
227- there is no need to call ``setNumberOfParameters() `` unless automatic fetching of parameter types is disabled.
228-
229- Two ways to supply parameters
230- -----------------------------
231-
232- There are two ways to supply parameters for a prepared statement, the first one is binding the parameters and
233- calling ``execute() ``
234-
235- ``public function bindValue(int $parameterNumber, mixed $value, mixed $type = null): $this ``
236- Sets the value for a parameter of a prepared query.
237-
238- ``$parameterNumber `` is 1-based, ``$type `` contains specification of parameter type. An exception will be raised
239- if ``$type `` is omitted / ``null `` and the parameter type is not already known.
240-
241- ``public function bindParam(int $parameterNumber, mixed &$param, mixed $type = null): $this ``
242- Binds a variable to a parameter of a prepared query.
243-
244- ``public function execute(): Result ``
245- Executes a prepared query using previously bound values. Note that the method does not accept arguments, all
246- values should be bound.
247-
248- .. code-block :: php
249-
250- $prepared = $connection->prepare('select * from foo where bar_id = $1 and foo_deleted = $2');
251- $result = $prepared
252- ->bindValue(1, 10)
253- ->bindValue(2, false)
254- ->execute();
255-
256- The second way is just
257-
258- ``public function executeParams(array $params): Result ``
259- Executes the prepared query using (only) the given parameters.
260-
261- ``$params `` should have integer keys with (0-based) key ``N `` corresponding to (1-based) statement placeholder
262- ``$(N + 1) ``. Unlike native `pg_execute() <https://www.php.net/manual/en/function.pg-execute.php >`__, array keys
263- will be respected and values mapped by keys rather than in "array order": passing ``['foo', 'bar'] `` will use
264- 'foo' for ``$1 `` and 'bar' for ``$2 ``, while ``[1 => 'foo', 0 => 'bar'] `` will use
265- 'bar' for ``$1 `` and 'foo' for ``$2 ``.
266-
267- .. code-block :: php
268-
269- $prepared = $connection->prepare('select * from foo where bar_id = $1 and foo_deleted = $2');
270- $result = $prepared->executeParams([10, false]);
271-
272-
273- .. note ::
274- These approaches are mutually exclusive, ``executeParams() `` will throw an exception if any parameter
275- has a bound value.
276-
277- Fetching parameter types automatically
278- --------------------------------------
279-
280- By default, ``PreparedStatement `` gets the types of the query parameters from Postgres (specifically, from
281- ``pg_prepared_statements `` system view), so there is no need to pass type specifications at all:
282-
283- .. code-block :: php
284-
285- $prepared = $connection->prepare(
286- 'select * from pg_catalog.pg_type where oid = any($1) order by typname'
287- );
288- $result = $prepared->executeParams([[16, 20, 603]]);
289-
290- This behaviour is controlled by static methods
291-
292- ``public static function setAutoFetchParameterTypes(bool $autoFetch): void ``
293- Sets whether parameter types should be automatically fetched after first preparing a statement.
294-
295- ``public static function getAutoFetchParameterTypes(): bool ``
296- Returns whether parameter types will be automatically fetched after first preparing a statement.
297- This defaults to ``true `` since version 3.0
298-
299- Changing that setting will affect all ``PreparedStatement `` objects created afterwards.
300-
301- The method that fetches types can also be called manually
302-
303- ``public function fetchParameterTypes(bool $overrideExistingTypes = false): $this ``
304- Fetches info about the types assigned to query parameters from the database.
305-
306- This method will always set parameter count to a correct value, but will not change existing type converters
307- for parameters unless ``$overrideExistingTypes `` is ``true ``.
308-
309- Specifying types manually
310- -------------------------
311-
312- It is assumed that the statement will be executed multiple times and that types of parameters and result columns
313- are quite unlikely to change between executions. Therefore, both query execution methods do not accept
314- type specifications and ``executeParams() `` will throw an exception if a type for a parameter is not known.
315-
316- Both parameter types and result types can be specified either when preparing a statement
317-
318- .. code-block :: php
319-
320- $prepared = $connection->prepare(
321- 'select row(foo_id, foo_added) from foo where bar = any($1::integer[])',
322- ['integer[]'],
323- [['id' => 'integer', 'added' => 'timestamptz']]
324- );
325-
326- or using the methods of ``PreparedStatement `` instance
327-
328- ``public function setParameterType(int $parameterNumber, mixed $type): $this ``
329- Sets the type for a parameter of a prepared query.
330-
331- ``public function setResultTypes(array $resultTypes): $this ``
332- Sets result types that will be passed to created ``Result `` instances.
333-
334- Additionally, ``bindValue() `` and ``bindParam() `` accept type specifications as well.
0 commit comments