Bug #75736 [Opn->Wfx]: PDO's constructor parameter for DSN prevents setting collation
Edit report at https://bugs.php.net/bug.php?id=75736&edit=1
ID: 75736
Updated by: dharman@php.net
Reported by: eagle at compu-lex dot de
Summary: PDO's constructor parameter for DSN prevents setting
collation
-Status: Open
+Status: Wont fix
Type: Bug
Package: PDO MySQL
Operating System: Debian 8 (Jessie)
PHP Version: 5.6.32
Block user comment: N
Private report: N
New Comment:
I'm sorry but it is highly unlikely we will ever implement this feature request. If you want,
you can submit a PR yourself. Reasons, why this is not going to be implemented in PHP anytime soon,
are:
1. MySQL C API doesn't provide any function to set the connection collation to anything other
than the default charset collation.
2. The benefit of such a feature would be extremely tiny. The connection collation is only used in a
comparison of string literals with themselves. This is a very narrow use case, for which exists a
very simple workaround. Use 'SET NAMES'.
3. This is not the responsibility of the client API. Setting charset is required for the data
transfer and escaping to work properly. Collation isn't required by the client API for
anything. Introducing such functionality would unnecessarily complicate client API or PDO. I do not
see any reason to do so.
Previous Comments:
------------------------------------------------------------------------
[2017-12-26 18:37:51] eagle at compu-lex dot de
Description:
------------
PHP's MySQL PDO driver can't set collations without an init command, although the
"charset=" parameter was introduced in PHP 5.3.6 to enable specifying the character set
without the need for an init command. (See https://secure.php.net/manual/en/ref.pdo-mysql.connection.php)
See Anthony Rutledge's answer over at https://stackoverflow.com/questions/25807202/how-to-specify-collation-with-pdo-without-set-names/32553447#32553447
for further details regarding this issue.
Test script:
---------------
<?php
$db = new PDO('mysql:host=HostnameOrIpHere;dbname=DbNameHere;charset=utf8',
'DbUserHere',
'DbPasswordHere',
array(PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
echo $db->query("SELECT COLLATION('foo')")->fetch(PDO::FETCH_NUM)[0];
?>
Expected result:
----------------
PDO's MySQL driver should allow for setting the collation explicitly, i. e. via proper value
for the "charset" parameter, e. g. changing test script's 2nd line to
$db = new PDO('mysql:host=HostnameOrIpHere;dbname=DbNameHere;charset=utf8_unicode_ci',
or by adding another parameter, e. g. "collation", for this should result in this output:
utf8_general_ci
But since MySQL always uses "charset_collation" (optionally combined with "_ci"
for case-insensitive comparison), I suggest only modifying which would be backwards compatible: utf8
-> works as before, utf8_unicode[_ci] -> utf8 for charset and unicode[_ci] for collation, if
present.
Actual result:
--------------
Test script's expected output, utf8_general_ci
Workaround: using PDO::MYSQL_ATTR_INIT_COMMAND with a value of "SET NAMES 'utf8'
COLLATE 'utf8_unicode_ci'" (including quotes) as a third array element in the test
script above, results in utf8_unicode_ci - but this should be considered as a temporary workaround
as PHP introduced the "charset=" parameter to eliminate the need for setting it via init
command.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=75736&edit=1
Thread (2 messages)