mirror of
https://github.com/sigmasternchen/php-doc-en
synced 2025-03-16 08:58:56 +00:00
190 lines
6.5 KiB
XML
190 lines
6.5 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<chapter xml:id="mysqlinfo.concepts" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Concepts</title>
|
|
<para>
|
|
These concepts are specific to the MySQL drivers for PHP.
|
|
</para>
|
|
|
|
<section xml:id="mysqlinfo.concepts.buffering">
|
|
<title>Buffered and Unbuffered queries</title>
|
|
|
|
<para>
|
|
Queries are using the buffered mode by default. This means that query results are
|
|
immediately transferred from the MySQL Server to PHP and then are kept in the memory
|
|
of the PHP process. This allows additional operations like counting the
|
|
number of rows, and moving (seeking) the current result pointer. It also allows
|
|
issuing further queries on the same connection while working on the result set.
|
|
The downside of the buffered mode is that larger result sets might require
|
|
quite a lot memory. The memory will be kept occupied till all references to the
|
|
result set are unset or the result set was explicitly freed, which will automatically
|
|
happen during request end at the latest. The terminology "store result" is also used
|
|
for buffered mode, as the whole result set is stored at once.
|
|
</para>
|
|
|
|
<note>
|
|
<para>
|
|
When using libmysqlclient as library PHP's memory limit won't count the memory used
|
|
for result sets unless the data is fetched into PHP variables. With mysqlnd
|
|
the memory accounted for will include the full result set.
|
|
</para>
|
|
</note>
|
|
|
|
<para>
|
|
Unbuffered MySQL queries execute the query and then return a <type>resource</type> while
|
|
the data is still waiting on the MySQL server for being fetched. This uses less memory
|
|
on the PHP-side, but can increase the load on the server. Unless the full result set was
|
|
fetched from the server no further queries can be sent over the same connection. Unbuffered
|
|
queries can also be referred to as "use result".
|
|
</para>
|
|
|
|
<para>
|
|
Following these characteristics buffered queries should be used in cases where you expect
|
|
only a limited result set or need to know the amount of returned rows before reading all
|
|
rows. Unbuffered mode should be used when you expect larger results.
|
|
</para>
|
|
|
|
<!-- @TODO
|
|
- Add list of issues people run into with unbuffered queries
|
|
- Add list of specific use cases for when unbuffered queries are useful
|
|
- Question: Unbuffered queries still require all rows to be returned or resource free before executing another? Applies to all extensions?
|
|
- Show "free_result" functions / unset usage with buffered queries 8double-check with Andrey on mysqlnd optimizations
|
|
-->
|
|
|
|
<para>
|
|
Because buffered queries are the default, the examples below will demonstrate how to
|
|
execute unbuffered queries with each API.
|
|
</para>
|
|
|
|
<example>
|
|
<title>Unbuffered query example: mysqli</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
|
|
$uresult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);
|
|
|
|
if ($uresult) {
|
|
while ($row = $uresult->fetch_assoc()) {
|
|
echo $row['Name'] . PHP_EOL;
|
|
}
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
|
|
<example>
|
|
<title>Unbuffered query example: pdo_mysql</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass');
|
|
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
|
|
|
|
$uresult = $pdo->query("SELECT Name FROM City");
|
|
if ($uresult) {
|
|
while ($row = $uresult->fetch(PDO::FETCH_ASSOC)) {
|
|
echo $row['Name'] . PHP_EOL;
|
|
}
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
|
|
<section xml:id="mysqlinfo.concepts.charset">
|
|
<title>Character sets</title>
|
|
|
|
<para>
|
|
Ideally a proper character set will be set at the server level, and doing this is described
|
|
within the <link xlink:href="&url.mysql.charsets.config;">Character Set Configuration</link>
|
|
section of the MySQL Server manual. Alternatively, each MySQL API offers a method to set
|
|
the character set at runtime.
|
|
</para>
|
|
|
|
<caution>
|
|
<title>The character set and character escaping</title>
|
|
<para>
|
|
The character set should be understood and defined, as it has an affect on every
|
|
action, and includes security implications. For example, the escaping mechanism
|
|
(e.g., <function>mysqli_real_escape_string</function> for mysqli and <methodname>PDO::quote</methodname> for PDO_MySQL) will adhere to
|
|
this setting. It is important to realize that these functions will not use the character
|
|
set that is defined with a query, so for example the following will not have an effect
|
|
on them:
|
|
</para>
|
|
</caution>
|
|
|
|
<example>
|
|
<title>Problems with setting the character set with SQL</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
|
|
|
|
// Will NOT affect $mysqli->real_escape_string();
|
|
$mysqli->query("SET NAMES utf8mb4");
|
|
|
|
// Will NOT affect $mysqli->real_escape_string();
|
|
$mysqli->query("SET CHARACTER SET utf8mb4");
|
|
|
|
// But, this will affect $mysqli->real_escape_string();
|
|
$mysqli->set_charset('utf8mb4');
|
|
|
|
// But, this will NOT affect it (UTF-8 vs utf8mb4) -- don't use dashes here
|
|
$mysqli->set_charset('UTF-8');
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
|
|
<para>
|
|
Below are examples that demonstrate how to properly alter the character set at runtime
|
|
using each API.
|
|
</para>
|
|
|
|
<note>
|
|
<title>Possible UTF-8 confusion</title>
|
|
<para>
|
|
Because character set names in MySQL do not contain dashes, the string
|
|
"utf8" is valid in MySQL to set the character set to UTF-8 (up to 3 byte UTF-8 Unicode Encoding). The string
|
|
"UTF-8" is not valid, as using "UTF-8" will fail to change the character set and will throw an error.
|
|
</para>
|
|
</note>
|
|
|
|
<example>
|
|
<title>Setting the character set example: mysqli</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
|
|
|
|
echo 'Initial character set: ' . $mysqli->character_set_name() . "\n";
|
|
|
|
if (!$mysqli->set_charset('utf8mb4')) {
|
|
printf("Error loading character set utf8mb4: %s\n", $mysqli->error);
|
|
exit;
|
|
}
|
|
|
|
echo 'Your current character set is: ' . $mysqli->character_set_name() . "\n";
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
|
|
<example>
|
|
<title>Setting the character set example: <link linkend="ref.pdo-mysql.connection">pdo_mysql</link></title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$pdo = new PDO("mysql:host=localhost;dbname=world;charset=utf8mb4", 'my_user', 'my_pass');
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
|
|
</section>
|
|
|
|
</chapter>
|