on 2019 Aug 26 9:03 PM
I'm trying to insert the multibyte string 'test 人造景' into an NVARCHAR field from PHP.
The platform is I'm running SA 17.0.9.4935 and php 5.5.9.
I have created the following test code to illustrate the issue:
$cstring = "UID=DBA;PWD=sql;Server=myserver;DBN=mydb;ASTART=No;host=localhost;CS=UTF-8"; $conn = sasql_connect( $cstring );$sql = "CREATE OR REPLACE TABLE UNICODE_TEST(ID INTEGER DEFAULT AUTOINCREMENT, NFIELD LONG NVARCHAR)"; $pstmt = sasql_prepare( $conn, $sql ); sasql_stmt_execute( $pstmt );
$sql = "INSERT INTO UNICODE_TEST(NFIELD) VALUES (?)"; $s = "tis is a test 人造景 again and again"; $pstmt = sasql_prepare( $conn, $sql ); sasql_stmt_bind_param_ex( $pstmt, 0, $s, "s", false ); sasql_stmt_execute( $pstmt );
$sql = "INSERT INTO UNICODE_TEST (NFIELD) VALUES (N'unitest1 / 人造景 again')"; $pstmt = sasql_prepare( $conn, $sql ); sasql_stmt_execute( $pstmt );
$sql = "INSERT INTO UNICODE_TEST (NFIELD) VALUES (UNISTR(N'unitest1 / \\u4eba\\u9020\\u666f'))"; $pstmt = sasql_prepare( $conn, $sql ); sasql_stmt_execute( $pstmt );
sasql_commit( $conn );
$sql = "SELECT * FROM UNICODE_TEST"; $rs = sasql_query($conn,$sql); while($obj = sasql_fetch_object($rs)){ var_dump($obj); } print "php default_charset: " . ini_get("default_charset")."\\n"; print "DONE!\\n";
If I run this on a database with the following settings, it works for all three cases:
Number,PropNum,PropName,PropDescription,Value 0,255,'CharSet','Character set used for CHAR data',UTF-8 0,256,'NcharCharSet','Character set used for NCHAR data',UTF-8 0,257,'MultiByteCharSet','Multi Byte Character Set ( on/off )',On 0,260,'NcharCollation','Name of collation used for NCHAR data',UCA 0,425,'HasNCHARLegacyCollationFix','Fixed NCHAR legacy collation implementation',On
and I get the expected output
$ php sasql_test06.php object(stdClass)#1 (2) { ["ID"]=> int(1) ["NFIELD"]=> string(29) "tis is a test 人造景 again" } object(stdClass)#2 (2) { ["ID"]=> int(2) ["NFIELD"]=> string(26) "unitest1 / 人造景 again" } object(stdClass)#1 (2) { ["ID"]=> int(3) ["NFIELD"]=> string(20) "unitest1 / 人造景" } php default_charset: UTF-8 DONE!
However, if I run it on a database with the following settings, it fails with the first 2 inserts but works with the third (where there are no real unicode characters, just their escaped representations):
Number,PropNum,PropName,PropDescription,Value 0,255,'CharSet','Character set used for CHAR data',windows-1252 0,256,'NcharCharSet','Character set used for NCHAR data',UTF-8 0,257,'MultiByteCharSet','Multi Byte Character Set ( on/off )',Off 0,260,'NcharCollation','Name of collation used for NCHAR data',UCA 0,423,'HasNCHARLegacyCollationFix','Fixed NCHAR legacy collation implementation',OnI get the following output with incorrect multibyte characters
$ php sasql_test06.php object(stdClass)#1 (2) { ["ID"]=> int(1) ["NFIELD"]=> string(23) "tis is a test again" } object(stdClass)#2 (2) { ["ID"]=> int(2) ["NFIELD"]=> string(20) "unitest1 / again" } object(stdClass)#1 (2) { ["ID"]=> int(3) ["NFIELD"]=> string(20) "unitest1 / 人造景" } php default_charset: UTF-8 DONE!I've also tried it without the
CS=UTF-8
connection parameter - different output but still incorrect.
Documentation (here) seems to say that if "Use a host variable to specify the Unicode character values" (which I am), this should work in the case where the default CharSet is windows-1252, given that the field I'm inserting into is defined as NVARCHAR which is UTF-8.
However, there is other documentation (here) that seems to indicate PHP uses the C API and "these are not available from the DBTools or C API interfaces".
I find the documentation confusing, but I fear that this may not supported in PHP!
It looks to me like the only way I can make this work is to unload my database into a new one that has both CHAR and NCHAR data set to UTF-8 (which will be very time-consuming in my case). Is that true? Or am I missing something here?
Terry
Request clarification before answering.
User | Count |
---|---|
77 | |
30 | |
10 | |
8 | |
8 | |
7 | |
7 | |
5 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.