Bug #54379 [Com]: PDO_OCI: UTF-8 output gets truncated
| From: | qing0088 at hotmail dot com | Date: | Mon, 29 Aug 2011 09:05:02 +0000 |
| Subject: | Bug #54379 [Com]: PDO_OCI: UTF-8 output gets truncated | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-163095@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=54379&edit=1
ID: 54379
Comment by: qing0088 at hotmail dot com
Reported by: sms at inbox dot ru
Summary: PDO_OCI: UTF-8 output gets truncated
Status: Open
Type: Bug
Package: PDO related
PHP Version: 5.3.6
Block user comment: N
Private report: N
New Comment:
http://www.officialbuffalobillsshop.com/trent-edwards-jersey-c-13_14.html Trent
Edwards Jersey
http://www.wholesaleusajerseys.us/soccer-club-c-286.html Soccer
Club Jerseys
http://www.wholesaleusajerseys.us/ Wholesale
Jerseys
Previous Comments:
------------------------------------------------------------------------
[2011-08-06 08:17:20] mitans02 at gmail dot com
I have same problem with UTF8 database and UTF8 client.
PDO_OCI should set string buffer length correct to handling UTF8.
Check also oracle OCI documents below:
http://download.oracle.com/docs/cd/B10500_01/server.920/a96529/ch6.htm#1004620
- Database settings
SQL>
1 SELECT PARAMETER, VALUE
2 FROM NLS_DATABASE_PARAMETERS
3* WHERE PARAMETER IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET')
PARAMETER VALUE
------------------------------ ------------------------------
NLS_CHARACTERSET AL32UTF8
NLS_NCHAR_CHARACTERSET AL16UTF16
- Table for test
CREATE TABLE mytable (col1 NVARCHAR2(20));
- Test data
INSERT INTO mytable VALUES('12345678901234567890'); /* 20 signle byte char */
INSERT INTO mytable
VALUES('ããããããããããããããããã¡ã¤ã¦ã¨');
/* 20 double byte char, Japanese */
- Test Program
<?php
print "NLS_LANG=".getenv('NLS_LANG')."\n\n";
$db = new
PDO("oci:dbname=//instance1.cf9klgqzy0gu.ap-northeast-1.rds.amazonaws.com:3306/mydb;charset=AL32UTF8",
"user", "pass");
$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
$stmt = $db->prepare("SELECT * FROM mytable");
$stmt->execute();
var_dump($stmt->fetchAll(PDO::FETCH_ASSOC));
?>
- Test Program Output
# php ocitest.php
NLS_LANG=Japanese_Japan.AL32UTF8
Warning: PDOStatement::fetchAll(): column 0 data was too large for buffer and was truncated to fit
it in /root/ocitest.php on line 9
array(2) {
[0]=>
array(1) {
["COL1"]=>
string(20) "12345678901234567890"
}
[1]=>
array(1) {
["COL1"]=>
string(40) "ããããããããããããã
}
}
- Client Environment
# uname -a
Linux localhost.localdomain 2.6.18-194.el5 #1 SMP Fri Apr 2 14:58:35 EDT 2010 i686 i686 i386
GNU/Linux
# rpm -qa | grep oracle
oracle-instantclient11.2-devel-11.2.0.2.0-1
oracle-instantclient11.2-sqlplus-11.2.0.2.0-1
oracle-instantclient11.2-basic-11.2.0.2.0-1
# php -v
PHP 5.3.6 (cli) (built: Aug 5 2011 09:15:02)
Copyright (c) 1997-2011 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies
- Suggest fix
Patch to oci_statement.c
# diff -u oci_statement.c oci_statement.c.new
--- oci_statement.c 2011-08-06 01:07:53.000000000 -0700
+++ oci_statement.c.new 2011-08-06 01:08:03.000000000 -0700
@@ -529,7 +529,7 @@
(param, OCI_DTYPE_PARAM, &colname, &namelen, OCI_ATTR_NAME,
S->err));
col->precision = scale;
- col->maxlen = data_size;
+ col->maxlen = ( data_size + 1 ) * sizeof(utext);
col->namelen = namelen;
col->name = estrndup((char *)colname, namelen);
------------------------------------------------------------------------
[2011-03-25 04:39:19] sms at inbox dot ru
Description:
------------
Data is stored in ANSI charset (CL8MSWIN1251) while connection uses UTF-8.
PDOStatement::fetchAll() generates warning and fields containing non-english characters gets
truncated. For example, PDO outputs only 53 UTF-8 russian characters for VARCHAR2(100) field.
MySQL's PDOStatement::fetchAll() works fine in the same situation.
Test script:
---------------
$pdo = new PDO('oci:dbname=[host];charset=UTF8', '[user]', '[pass]');
$cmd = $pdo->query('SELECT * FROM user');
var_dump($cmd->fetchAll());
Expected result:
----------------
Table field(s) not truncated, no warnings
Actual result:
--------------
Table field(s) gets truncated, PHP warning:
PDOStatement::fetchAll() [<a
href='pdostatement.fetchall'>pdostatement.fetchall</a>]: column 0 data was too
large for buffer and was truncated to fit it
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=54379&edit=1