Added a concepts section about character sets, and linked to it in various places.

This is an improved fix for PHP Bug #54605


git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@326024 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
Philip Olson 2012-06-08 05:21:09 +00:00
parent 59b8134015
commit 41f14ef421
7 changed files with 136 additions and 23 deletions

View file

@ -44,14 +44,11 @@
<caution>
<title>Security: the default character set</title>
<para>
Always set your character set at the server level, or with <function>mysql_set_charset</function>.
</para>
<para>
<function>mysql_real_escape_string</function> will take into account the character set
if it is set by either the MySQL Server (e.g., via its <literal>default-character-set</literal> directive)
or from <function>mysql_set_charset</function>. But, it will not use the character set that is set with
an SQL query, like as a <literal>SET CHARACTER SET ...</literal> or <literal>SET NAMES ...</literal> query
with <function>mysql_query</function>.
The character set must be set either at the server level, or with
the API function <function>mysql_set_charset</function> for it to affect
<function>mysql_real_escape_string</function>. See the concepts section
on <link linkend="mysqlinfo.concepts.charset">character sets</link> for
more information.
</para>
</caution>
</refsect1>

View file

@ -62,8 +62,9 @@
<note>
<para>
This is the preferred way to change the charset. Using
<function>mysql_query</function> to execute <literal>SET NAMES ..</literal>
is not recommended.
<function>mysql_query</function> to set it (such as <literal>SET NAMES utf8</literal>)
is not recommended. See the <link linkend="mysqlinfo.concepts.charset">MySQL character set concepts</link>
section for more information.
</para>
</note>
</refsect1>

View file

@ -32,14 +32,11 @@
<caution>
<title>Security: the default character set</title>
<para>
Always set your character set at the server level, or with <function>mysqli_set_charset</function>.
</para>
<para>
<function>mysqli_real_escape_string</function> will take into account the character set
if it is set by either the MySQL Server (e.g., via its <literal>default-character-set</literal> directive)
or from <function>mysqli_set_charset</function>. But, it will not use the character set that is set with
an SQL query, like as a <literal>SET CHARACTER SET ...</literal> or <literal>SET NAMES ...</literal> query
with <function>mysqli_query</function>.
The character set must be set either at the server level, or with
the API function <function>mysqli_set_charset</function> for it to affect
<function>mysqli_real_escape_string</function>. See the concepts section
on <link linkend="mysqlinfo.concepts.charset">character sets</link> for
more information.
</para>
</caution>
</refsect1>

View file

@ -61,8 +61,9 @@
<note>
<para>
This is the preferred way to change the charset. Using
<function>mysqli::query</function> to execute <literal>SET NAMES ..</literal>
is not recommended.
<function>mysqli_query</function> to set it (such as <literal>SET NAMES utf8</literal>)
is not recommended. See the <link linkend="mysqlinfo.concepts.charset">MySQL character set concepts</link>
section for more information.
</para>
</note>
</refsect1>

View file

@ -11,7 +11,7 @@
<para>
Queries are using the buffered mode by default. This means that query results are
immediately transfered from the MySQL Server to PHP in is then kept in the memory
immediately transferred from the MySQL Server to PHP in is then 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.
@ -19,7 +19,7 @@
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 the latest. The terminology "store result" is also used
for uffered mode, as the whole result set is stored at once.
for buffered mode, as the whole result set is stored at once.
</para>
<note>
@ -114,4 +114,111 @@ if ($uresult) {
</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, <function>mysql_real_escape_string</function>
for mysql, 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 utf8");
// Will not affect $mysqli->real_escape_string();
$mysqli->query("SET CHARACTER SET utf8");
// But, this will affect $mysqli->real_escape_string();
$mysqli->set_charset('utf8')) {
?>
]]>
</programlisting>
</example>
<para>
Below are examples that demonstrate how to properly alter the character set at runtime
using each each API.
</para>
<example>
<title>Setting the character set example: mysqli</title>
<programlisting role="php">
<![CDATA[
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
if (!$mysqli->set_charset('utf8')) {
printf("Error loading character set utf8: %s\n", $mysqli->error);
} else {
printf("Current character set: %s\n", $mysqli->character_set_name());
}
print_r( $mysqli->get_charset() );
?>
]]>
</programlisting>
</example>
<example>
<title>Setting the character set example: <link linkend="ref.pdo-mysql.connection">pdo_mysql</link></title>
<para>
Note: This only works as of PHP 5.3.6.
</para>
<programlisting role="php">
<![CDATA[
<?php
$pdo = new PDO("mysql:host=localhost;dbname=world;charset=utf8", 'my_user', 'my_pass');
?>
]]>
</programlisting>
</example>
<example>
<title>Setting the character set example: mysql</title>
<programlisting role="php">
<![CDATA[
<?php
$conn = mysql_connect("localhost", "my_user", "my_pass");
$db = mysql_select_db("world");
if (!mysql_set_charset('utf8', $conn)) {
echo "Error: Unable to set the character set.\n";
exit;
}
echo 'Your current character set is: ' . mysql_client_encoding($conn);
?>
]]>
</programlisting>
</example>
</section>
</chapter>

View file

@ -34,6 +34,15 @@
Not all PDO drivers implement this method (notably PDO_ODBC). Consider
using prepared statements instead.
</para>
<caution>
<title>Security: the default character set</title>
<para>
The character set must be set either on the server level, or within the
database connection itself (depending on the driver) for it to affect
<methodname>PDO::quote</methodname>. See the <link linkend="pdo.drivers">driver-specific
documentation</link> for more information.
</para>
</caution>
</refsect1>
<refsect1 role="parameters">
&reftitle.parameters;

View file

@ -90,7 +90,8 @@
<term><literal>charset</literal></term>
<listitem>
<para>
The character set.
The character set. See the <link linkend="mysqlinfo.concepts.charset">character set</link>
concepts documentation for more information.
</para>
<para>
Prior to PHP 5.3.6, this element was silently ignored. The same