support for non-utf8 locales (#598)

* support non-utf8 locales
This commit is contained in:
v-susanh 2017-11-20 17:56:45 -08:00 committed by GitHub
parent 325e5d20fe
commit 54f1e5e22f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 342 additions and 126 deletions

View file

@ -9,6 +9,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && apt-get update && \
apt-utils \
autoconf \
curl \
libcurl3 \
g++ \
gcc \
git \
@ -28,17 +29,14 @@ ENV TEST_PHP_SQL_SERVER sql
ENV TEST_PHP_SQL_UID sa
ENV TEST_PHP_SQL_PWD Password123
# add locale iso-8859-1
RUN sed -i 's/# en_US ISO-8859-1/en_US ISO-8859-1/g' /etc/locale.gen
RUN locale-gen en_US
# set locale to utf-8
RUN locale-gen en_US.UTF-8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'
#install ODBC driver
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
RUN export DEBIAN_FRONTEND=noninteractive && apt-get update && ACCEPT_EULA=Y apt-get install -y msodbcsql mssql-tools
ENV PATH="/opt/mssql-tools/bin:${PATH}"
#install coveralls
RUN pip install --upgrade pip && pip install cpp-coveralls
@ -47,8 +45,14 @@ RUN pip install --upgrade pip && pip install cpp-coveralls
#another option is to copy source to build directory on image
RUN mkdir -p $PHPSQLDIR
COPY . $PHPSQLDIR
WORKDIR $PHPSQLDIR/source/
#install ODBC 17 preview driver
WORKDIR $PHPSQLDIR
RUN export DEBIAN_FRONTEND=noninteractive && apt-get update && ACCEPT_EULA=Y dpkg -i "./ODBC 17 binaries preview/Ubuntu 16/msodbcsql_17.0.0.1-1_amd64.deb"
RUN export DEBIAN_FRONTEND=noninteractive && apt-get update && ACCEPT_EULA=Y dpkg -i "./ODBC 17 binaries preview/Ubuntu 16/mssql-tools_17.0.0.1-1_amd64.deb"
ENV PATH="/opt/mssql-tools/bin:${PATH}"
WORKDIR $PHPSQLDIR/source/
RUN chmod +x ./packagize.sh
RUN /bin/bash -c "./packagize.sh"
@ -79,4 +83,4 @@ RUN chmod +x ./entrypoint.sh
CMD /bin/bash ./entrypoint.sh
ENV REPORT_EXIT_STATUS 1
ENV TEST_PHP_EXECUTABLE /usr/bin/php
ENV TEST_PHP_EXECUTABLE /usr/bin/php

View file

@ -39,6 +39,12 @@ void core_sqlsrv_minit( _Outptr_ sqlsrv_context** henv_cp, _Inout_ sqlsrv_contex
SQLSRV_STATIC_ASSERT( sizeof( sqlsrv_sqltype ) == sizeof( zend_long ) );
SQLSRV_STATIC_ASSERT( sizeof( sqlsrv_phptype ) == sizeof( zend_long ));
#ifndef _WIN32
// set locale from environment
// this is necessary for ODBC and MUST be done before connection
setlocale(LC_ALL, "");
#endif
*henv_cp = *henv_ncp = SQL_NULL_HANDLE; // initialize return values to NULL
try {

View file

@ -27,6 +27,17 @@
#include <locale>
#define CP_UTF8 65001
#define CP_ISO8859_1 28591
#define CP_ISO8859_2 28592
#define CP_ISO8859_3 28593
#define CP_ISO8859_4 28594
#define CP_ISO8859_5 28595
#define CP_ISO8859_6 28596
#define CP_ISO8859_7 28597
#define CP_ISO8859_8 28598
#define CP_ISO8859_9 28599
#define CP_ISO8859_13 28603
#define CP_ISO8859_15 28605
#define CP_UTF16 1200
#define CP_ACP 0 // default to ANSI code page
@ -178,14 +189,15 @@ private:
SystemLocale & operator=( const SystemLocale & );
std::locale * m_pLocale;
UINT m_uAnsiCP;
explicit SystemLocale( const char * localeName );
~SystemLocale();
static UINT ExpandSpecialCP( UINT codepage )
{
// Convert CP_ACP, CP_OEM to CP_UTF8
return (codepage < 2 ? CP_UTF8 : codepage);
// skip SQLSRV_ENCODING_CHAR
return (codepage <= 3 ? Singleton().m_uAnsiCP : codepage);
}
// Returns the number of bytes this UTF8 code point expects
@ -217,7 +229,7 @@ private:
inline UINT SystemLocale::AnsiCP() const
{
return CP_UTF8;
return m_uAnsiCP;
}
inline UINT SystemLocale::MaxCharCchSize( UINT codepage )

View file

@ -1,5 +1,5 @@
//---------------------------------------------------------------------------------------------------------------------------------
// File: LocalizationImpl.hpp
// File: localizationimpl.cpp
//
// Contents: Contains non-inline code for the SystemLocale class
// Must be included in one c/cpp file per binary
@ -71,6 +71,17 @@ const cp_iconv cp_iconv::g_cp_iconv[] = {
{ 1256, "CP1256//TRANSLIT" },
{ 1257, "CP1257//TRANSLIT" },
{ 1258, "CP1258//TRANSLIT" },
{ CP_ISO8859_1, "ISO8859-1//TRANSLIT" },
{ CP_ISO8859_2, "ISO8859-2//TRANSLIT" },
{ CP_ISO8859_3, "ISO8859-3//TRANSLIT" },
{ CP_ISO8859_4, "ISO8859-4//TRANSLIT" },
{ CP_ISO8859_5, "ISO8859-5//TRANSLIT" },
{ CP_ISO8859_6, "ISO8859-6//TRANSLIT" },
{ CP_ISO8859_7, "ISO8859-7//TRANSLIT" },
{ CP_ISO8859_8, "ISO8859-8//TRANSLIT" },
{ CP_ISO8859_9, "ISO8859-9//TRANSLIT" },
{ CP_ISO8859_13, "ISO8859-13//TRANSLIT" },
{ CP_ISO8859_15, "ISO8859-15//TRANSLIT" },
{ 12000, "UTF-32LE" }
};
const size_t cp_iconv::g_cp_iconv_count = ARRAYSIZE(cp_iconv::g_cp_iconv);
@ -270,7 +281,42 @@ using namespace std;
SystemLocale::SystemLocale( const char * localeName )
: m_pLocale( new std::locale(localeName) )
, m_uAnsiCP(CP_UTF8)
{
struct LocaleCP
{
const char* localeName;
UINT codePage;
};
#define CPxxx(cp) { "CP" #cp, cp }
#define ISO8859(n) { "ISO-8859-" #n, CP_ISO8859_ ## n }, \
{ "8859_" #n, CP_ISO8859_ ## n }, \
{ "ISO8859-" #n, CP_ISO8859_ ## n }, \
{ "ISO8859" #n, CP_ISO8859_ ## n }, \
{ "ISO_8859-" #n, CP_ISO8859_ ## n }, \
{ "ISO_8859_" #n, CP_ISO8859_ ## n }
const LocaleCP lcpTable[] = {
{ "utf8", CP_UTF8 },
{ "UTF-8", CP_UTF8 },
CPxxx(1252), CPxxx(850), CPxxx(437), CPxxx(874), CPxxx(932), CPxxx(936), CPxxx(949), CPxxx(950),
CPxxx(1250), CPxxx(1251), CPxxx(1253), CPxxx(1254), CPxxx(1255), CPxxx(1256), CPxxx(1257), CPxxx(1258),
ISO8859(1), ISO8859(2), ISO8859(3), ISO8859(4), ISO8859(5), ISO8859(6),
ISO8859(7), ISO8859(8), ISO8859(9), ISO8859(13), ISO8859(15),
{ "UTF-32LE", 12000 }
};
if (localeName)
{
const char *charsetName = strchr(localeName, '.');
charsetName = charsetName ? charsetName + 1 : localeName;
for (const LocaleCP& lcp : lcpTable)
{
if (!strncasecmp(lcp.localeName, charsetName, strlen(lcp.localeName)))
{
m_uAnsiCP = lcp.codePage;
return;
}
}
}
}
SystemLocale::~SystemLocale()
@ -285,7 +331,8 @@ const SystemLocale & SystemLocale::Singleton()
#if !defined(__GNUC__) || defined(NO_THREADSAFE_STATICS)
#error "Relying on GCC's threadsafe initialization of local statics."
#endif
static const SystemLocale s_Default( "en_US.utf-8" );
// get locale from environment and set as default
static const SystemLocale s_Default(setlocale(LC_ALL, NULL));
return s_Default;
}

View file

@ -454,4 +454,15 @@ function handleErrors()
}
}
?>
// non-UTF8 locale support in ODBC 17 and above only
function isLocaleSupported()
{
$conn = AE\connect();
$msodbcsql_ver = sqlsrv_client_info($conn)['DriverVer'];
if (explode(".", $msodbcsql_ver)[0] < 17) {
return false;
}
}
?>

View file

@ -9,7 +9,7 @@
*/
function getTestData($index)
function getTestData_UTF8($index)
{
$inputs = null;
switch ($index)

View file

@ -732,12 +732,13 @@ function getInsertArray($index)
{
if (! UseUTF8data()) {
require_once('MsData.inc');
return getTestData($index);
} else {
require_once('MsData_UTF8.inc');
return getTestData_UTF8($index);
}
// get array of input values
return getTestData($index);
}
/**
@ -1184,4 +1185,4 @@ function getSampleData($k)
}
}
?>
?>

View file

@ -1,9 +1,14 @@
--TEST--
Fetch Field Data Test verifies the data retrieved via "sqlsrv_get_field"
Fetch Field Data Test verifies the data retrieved via sqlsrv_get_field
--ENV--
PHPT_EXEC=true
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
<?
// locale must be set before 1st connection
if ( !isWindows() ) {
setlocale(LC_ALL, "en_US.ISO-8859-1");
}
?>
--FILE--
<?php
@ -11,13 +16,15 @@ require_once('MsCommon.inc');
function fetchFields()
{
$testName = "Fetch - Field Data";
startTest($testName);
setup();
$tableName = 'TC43test';
$conn1 = AE\connect();
if (useUTF8Data()) {
$conn1 = AE\connect(array('CharacterSet'=>'UTF-8'));
} else {
$conn1 = AE\connect();
}
AE\createTestTable($conn1, $tableName);
$startRow = 1;
@ -62,8 +69,6 @@ function fetchFields()
dropTable($conn1, $tableName);
sqlsrv_close($conn1);
endTest($testName);
}
function checkData($col, $actual, $expected)
@ -91,16 +96,36 @@ function checkData($col, $actual, $expected)
return ($success);
}
if (! isWindows()) {
setUTF8Data(true);
if (!isWindows()) {
setlocale(LC_ALL, "en_US.ISO-8859-1");
}
$testName = "Fetch - Field Data";
// test ansi only if windows or non-UTF8 locales are supported (ODBC 17 and above)
startTest($testName);
if (isWindows() || isLocaleSupported()) {
try {
setUTF8Data(false);
fetchFields();
} catch (Exception $e) {
echo $e->getMessage();
}
}
endTest($testName);
// test utf8
startTest($testName);
try {
setUTF8Data(true);
fetchFields();
} catch (Exception $e) {
echo $e->getMessage();
}
setUTF8Data(false);
endTest($testName);
?>
--EXPECT--
Test "Fetch - Field Data" completed successfully.
Test "Fetch - Field Data" completed successfully.

View file

@ -6,24 +6,25 @@ by checking all fetch type modes.
--ENV--
PHPT_EXEC=true
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
<?
// locale must be set before 1st connection
if ( !isWindows() ) {
setlocale(LC_ALL, "en_US.ISO-8859-1");
}
?>
--FILE--
<?php
require_once('MsCommon.inc');
function fetchRow($minFetchMode, $maxFetchMode)
{
$testName = "Fetch - Array";
startTest($testName);
if (!isMarsSupported()) {
endTest($testName);
return;
}
setup();
$tableName = 'TC44test';
if (!isWindows()) {
if (useUTF8Data()) {
$conn1 = AE\connect(array( 'CharacterSet'=>'UTF-8' ));
} else {
$conn1 = AE\connect();
@ -43,7 +44,6 @@ function fetchRow($minFetchMode, $maxFetchMode)
} else {
$count = sqlsrv_num_fields($stmt1);
if ($count != $numFields) {
setUTF8Data(false);
die("Unexpected number of fields: $count");
}
}
@ -73,8 +73,6 @@ function fetchRow($minFetchMode, $maxFetchMode)
dropTable($conn1, $tableName);
sqlsrv_close($conn1);
endTest($testName);
}
function fetchArray($stmt, $stmtRef, $mode, $rows, $fields)
@ -104,13 +102,11 @@ function fetchArray($stmt, $stmtRef, $mode, $rows, $fields)
}
$rowSize = count($row);
if ($rowSize != $size) {
setUTF8Data(false);
die("Row array has an incorrect size: ".$rowSize);
}
$rowRref = sqlsrv_fetch($stmtRef);
for ($j = 0; $j < $fields; $j++) {
if (!checkData($row, $stmtRef, $j, $fetchMode)) {
setUTF8Data(false);
die("Data corruption on row ".($i + 1)." column ".($j + 1));
}
}
@ -155,17 +151,37 @@ function checkData($row, $stmt, $index, $mode)
return ($success);
}
// locale must be set before 1st connection
if (!isWindows()) {
setUTF8Data(true);
setlocale(LC_ALL, "en_US.ISO-8859-1");
}
global $testName;
$testName = "Fetch - Array";
// test ansi only if windows or non-UTF8 locales are supported (ODBC 17 and above)
startTest($testName);
if (isWindows() || isLocaleSupported()) {
try {
setUTF8Data(false);
fetchRow(1, 4);
} catch (Exception $e) {
echo $e->getMessage();
}
}
endTest($testName);
// test utf8
startTest($testName);
try {
setUTF8Data(true);
fetchRow(1, 4);
} catch (Exception $e) {
echo $e->getMessage();
}
setUTF8Data(false);
endTest($testName);
?>
--EXPECT--
Test "Fetch - Array" completed successfully.
Test "Fetch - Array" completed successfully.

View file

@ -5,24 +5,29 @@ Verifies the functionality of "sqlsrv_next_result"
--ENV--
PHPT_EXEC=true
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
<?
// locale must be set before 1st connection
if ( !isWindows() ) {
setlocale(LC_ALL, "en_US.ISO-8859-1");
}
?>
--FILE--
<?php
require_once('MsCommon.inc');
function fetchFields()
{
$testName = "Fetch - Next Result";
startTest($testName);
if (!IsMarsSupported()) {
endTest($testName);
return;
}
setup();
$tableName = 'TC46test';
$conn1 = AE\connect();
if (useUTF8Data()) {
$conn1 = AE\connect(array('CharacterSet'=>'UTF-8'));
} else {
$conn1 = AE\connect();
}
AE\createTestTable($conn1, $tableName);
$noRows = 10;
@ -77,21 +82,39 @@ function fetchFields()
dropTable($conn1, $tableName);
sqlsrv_close($conn1);
endTest($testName);
}
// locale must be set before 1st connection
if (!isWindows()) {
setUTF8Data(true);
setlocale(LC_ALL, "en_US.ISO-8859-1");
}
global $testName;
$testName = "Fetch - Next Result";
// test ansi only if windows or non-UTF8 locales are supported (ODBC 17 and above)
startTest($testName);
if (isWindows() || isLocaleSupported()) {
try {
setUTF8Data(false);
fetchFields();
} catch (Exception $e) {
echo $e->getMessage();
}
}
endTest($testName);
// test utf8
startTest($testName);
try {
setUTF8Data(true);
fetchFields();
} catch (Exception $e) {
echo $e->getMessage();
}
setUTF8Data(false);
endTest($testName);
?>
--EXPECT--
Test "Fetch - Next Result" completed successfully.
Test "Fetch - Next Result" completed successfully.

View file

@ -6,19 +6,20 @@ can be successfully retrieved as streams.
--ENV--
PHPT_EXEC=true
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
<?// locale must be set before 1st connection
if ( !isWindows() ) {
setlocale(LC_ALL, "en_US.ISO-8859-1");
}
?>
--FILE--
<?php
require_once('MsCommon.inc');
function streamRead($noRows, $startRow)
{
$testName = "Stream - Read";
startTest($testName);
setup();
$tableName = 'TC51test';
if (! isWindows()) {
if (useUTF8Data()) {
$conn1 = AE\connect(array( 'CharacterSet'=>'UTF-8' ));
} else {
$conn1 = AE\connect();
@ -51,8 +52,6 @@ function streamRead($noRows, $startRow)
dropTable($conn1, $tableName);
sqlsrv_close($conn1);
endTest($testName);
}
function verifyStream($stmt, $row, $colIndex)
@ -80,7 +79,6 @@ function verifyStream($stmt, $row, $colIndex)
fclose($stream);
$data = AE\getInsertData($row, $col);
if (!checkData($col, $value, $data)) {
setUTF8Data(false);
trace("Data corruption on row $row column $col\n");
die("Data corruption on row $row column $col\n");
}
@ -117,18 +115,37 @@ function checkData($col, $actual, $expected)
return ($success);
}
if (! isWindows()) {
setUTF8Data(true);
// locale must be set before 1st connection
if (!isWindows()) {
setlocale(LC_ALL, "en_US.ISO-8859-1");
}
global $testName;
$testName = "Stream - Read";
// test ansi only if windows or non-UTF8 locales are supported (ODBC 17 and above)
startTest($testName);
if (isWindows() || isLocaleSupported()) {
try {
setUTF8Data(false);
streamRead(20, 1);
} catch (Exception $e) {
echo $e->getMessage();
}
}
endTest($testName);
// test utf8
startTest($testName);
try {
setUTF8Data(true);
streamRead(20, 1);
} catch (Exception $e) {
echo $e->getMessage();
}
setUTF8Data(false);
endTest($testName);
?>
--EXPECT--
Test "Stream - Read" completed successfully.
Test "Stream - Read" completed successfully.

View file

@ -5,20 +5,23 @@ Verifies the streaming behavior with scrollable resultsets.
--ENV--
PHPT_EXEC=true
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
<?
// locale must be set before 1st connection
if ( !isWindows() ) {
setlocale(LC_ALL, "en_US.ISO-8859-1");
}
?>
--FILE--
<?php
require_once('MsCommon.inc');
function streamScroll($noRows, $startRow)
{
$testName = "Stream - Scrollable";
startTest($testName);
setup();
$tableName = "TC55test";
if (! isWindows()) {
$conn1 = AE\connect(array( 'CharacterSet'=>'UTF-8' ));
if (useUTF8Data()) {
$conn1 = AE\connect(array('CharacterSet'=>'UTF-8'));
} else {
$conn1 = AE\connect();
}
@ -84,8 +87,6 @@ function streamScroll($noRows, $startRow)
dropTable($conn1, $tableName);
sqlsrv_close($conn1);
endTest($testName);
}
function verifyStream($stmt, $row, $colIndex)
@ -150,16 +151,37 @@ function checkData($col, $actual, $expected)
return ($success);
}
if (! isWindows()) {
setUTF8Data(true);
// locale must be set before 1st connection
if (!isWindows()) {
setlocale(LC_ALL, "en_US.ISO-8859-1");
}
global $testName;
$testName = "Stream - Scrollable";
// test ansi only if windows or non-UTF8 locales are supported (ODBC 17 and above)
startTest($testName);
if (isWindows() || isLocaleSupported()) {
try {
setUTF8Data(false);
streamScroll(20, 1);
} catch (Exception $e) {
echo $e->getMessage();
}
}
endTest($testName);
// test utf8
startTest($testName);
try {
setUTF8Data(true);
streamScroll(20, 1);
} catch (Exception $e) {
echo $e->getMessage();
}
setUTF8Data(false);
endTest($testName);
?>
--EXPECT--
Test "Stream - Scrollable" completed successfully.
Test "Stream - Scrollable" completed successfully.

View file

@ -1,20 +1,32 @@
--TEST--
streaming large amounts of data into a database and getting it out as a string exactly the same.
--SKIPIF--
<?php require('skipif.inc'); ?>
<?
// locale must be set before 1st connection
if ( !isWindows() ) {
setlocale(LC_ALL, "en_US.ISO-8859-1");
}
php require('skipif.inc');
?>
--FILE--
<?php
require_once("MsCommon.inc");
function runtest()
{
set_time_limit(0);
sqlsrv_configure('WarningsReturnAsErrors', 0);
sqlsrv_configure('LogSeverity', SQLSRV_LOG_SEVERITY_ALL);
sqlsrv_configure('LogSubsystems', SQLSRV_LOG_SYSTEM_OFF);
require_once("MsCommon.inc");
$notWindows = (! isWindows());
// required charset UTF-8 when NOT running in Windows
$conn1 = ($notWindows) ? connect(array( 'CharacterSet'=>'UTF-8' )) : connect() ;
$useUTF8 = useUTF8Data();
if ($useUTF8) {
$conn1 = connect(array('CharacterSet'=>'UTF-8'));
} else {
$conn1 = connect();
}
if ($conn1 === false) {
fatalError("Failed to connect");
}
@ -31,18 +43,17 @@ streaming large amounts of data into a database and getting it out as a string e
sqlsrv_free_stmt($stmt2);
sqlsrv_close($conn1);
if ($notWindows) {
$conn2 = connect(array( 'CharacterSet' =>'utf-8' ));
if ($useUTF8) {
$conn2 = connect(array('CharacterSet'=>'UTF-8'));
} else {
$conn2 = connect();
}
if ($conn2 === false) {
echo "sqlsrv_connect failed 2nd.\n";
die(print_r(sqlsrv_errors(), true));
}
if ($notWindows) {
if ($useUTF8) {
require('test_stream_large_data_UTF8.inc');
GenerateInputUTF8Data();
} else {
@ -147,27 +158,27 @@ streaming large amounts of data into a database and getting it out as a string e
$metadata1 = sqlsrv_field_metadata($stmt8);
$count = count($metadata1);
sqlsrv_fetch($stmt8);
$value1 = GetField($stmt8, 13, $notWindows);
$value1 = GetField($stmt8, 13, $useUTF8);
$lens1[$i++] = strlen($value1) . "\n";
$fout = fopen("varchar_max.out", "w");
fwrite($fout, $value1);
fclose($fout);
$value2 = GetField($stmt8, 16, $notWindows);
$value2 = GetField($stmt8, 16, $useUTF8);
$lens1[$i++] = strlen($value2) . "\n";
$fout = fopen("nvarchar_max.out", "w");
fwrite($fout, $value2);
fclose($fout);
$value3 = GetField($stmt8, 17, $notWindows);
$value3 = GetField($stmt8, 17, $useUTF8);
$lens1[$i++] = strlen($value3) . "\n";
$fout = fopen("text.out", "w");
fwrite($fout, $value3);
fclose($fout);
$value4 = GetField($stmt8, 18, $notWindows);
$value4 = GetField($stmt8, 18, $useUTF8);
$lens1[$i++] = strlen($value4) . "\n";
$fout = fopen("ntext.out", "w");
fwrite($fout, $value4);
fclose($fout);
$value5 = GetField($stmt8, 27, $notWindows);
$value5 = GetField($stmt8, 27, $useUTF8);
$lens1[$i++] = strlen($value5) . "\n";
$fout = fopen("xml.out", "w");
fwrite($fout, $value5);
@ -189,57 +200,78 @@ streaming large amounts of data into a database and getting it out as a string e
$metadata1 = sqlsrv_field_metadata($stmt8);
$count = count($metadata1);
sqlsrv_fetch($stmt8);
$value1 = GetField($stmt8, 13, $notWindows);
$value1 = GetField($stmt8, 13, $useUTF8);
$lens2[$i++] = strlen($value1);
$value2 = GetField($stmt8, 16, $notWindows);
$value2 = GetField($stmt8, 16, $useUTF8);
$lens2[$i++] = strlen($value2) . "\n";
$value3 = GetField($stmt8, 17, $notWindows);
$value3 = GetField($stmt8, 17, $useUTF8);
$lens2[$i++] = strlen($value3) . "\n";
$value4 = GetField($stmt8, 18, $notWindows);
$value4 = GetField($stmt8, 18, $useUTF8);
$lens2[$i++] = strlen($value4) . "\n";
$value5 = GetField($stmt8, 27, $notWindows);
$value5 = GetField($stmt8, 27, $useUTF8);
$lens2[$i++] = strlen($value5) . "\n";
CompareLengths($filesizes, $lens1, $lens2, $i, $notWindows);
CompareLengths($filesizes, $lens1, $lens2, $i, $useUTF8);
echo "Test finished\n";
sqlsrv_free_stmt($stmt8);
sqlsrv_close($conn2);
}
function GetField($stmt, $idx, $notWindows)
{
if ($notWindows) {
return sqlsrv_get_field($stmt, $idx, SQLSRV_PHPTYPE_STRING('UTF-8'));
} else {
return sqlsrv_get_field($stmt, $idx, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR));
}
function GetField($stmt, $idx, $useUTF8)
{
if ($useUTF8) {
return sqlsrv_get_field($stmt, $idx, SQLSRV_PHPTYPE_STRING('UTF-8'));
} else {
return sqlsrv_get_field($stmt, $idx, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR));
}
}
function CompareLengths($filesizes, $lens1, $lens2, $count, $notWindows)
{
if ($notWindows) {
// in Linux or Mac, same field should return same length, and strlen() for Unicode data is different
for ($i = 0; $i < $count; $i++) {
$length = $filesizes[$i];
if ($lens1[$i] != $length || $lens2[$i] != $length) {
echo "Data length mismatched!\n";
}
}
} else {
// in Windows, all lengths are equal
$length = 1048576; // number of characters in the data (in ANSI encoding)
for ($i = 0; $i < $count; $i++) {
if ($filesizes[$i] != $length) {
echo "File $i size unexpected\n";
}
if ($lens1[$i] != $length || $lens2[$i] != $length) {
echo "Data length mismatched!\n";
}
function CompareLengths($filesizes, $lens1, $lens2, $count, $useUTF8)
{
if ($useUTF8) {
// in Linux or Mac, same field should return same length, and strlen() for Unicode data is different
for ($i = 0; $i < $count; $i++) {
$length = $filesizes[$i];
if ($lens1[$i] != $length || $lens2[$i] != $length) {
echo "Data length mismatched!\n";
}
}
} else {
// in Windows, all lengths are equal
$length = 1048576; // number of characters in the data (in ANSI encoding)
for ($i = 0; $i < $count; $i++) {
if ($filesizes[$i] != $length) {
echo "File $i size unexpected\n";
}
if ($lens1[$i] != $length || $lens2[$i] != $length) {
echo "Data length mismatched!\n";
}
}
}
}
// locale must be set before 1st connection
if (!isWindows()) {
setlocale(LC_ALL, "en_US.ISO-8859-1");
}
// test ansi only if windows or non-UTF8 locales are supported (ODBC 17 and above)
if (isWindows() || isLocaleSupported()) {
setUTF8Data(false);
runtest();
}
else {
echo "Test finished\n";
}
// test utf8
setUTF8Data(true);
runtest();
?>
--EXPECT--
Test finished
Test finished