Skip to content

Commit 23f92ef

Browse files
authored
Added configurable options for setting locales (#1069)
#1063
1 parent eeec2f8 commit 23f92ef

25 files changed

+477
-41
lines changed

Dockerfile-msphpsql

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,14 @@ ENV TEST_PHP_SQL_PWD Password123
3939
# update PATH after ODBC driver and tools are installed
4040
ENV PATH="/opt/mssql-tools/bin:${PATH}"
4141

42-
# add locale iso-8859-1
42+
# add locales for testing
4343
RUN sed -i 's/# en_US ISO-8859-1/en_US ISO-8859-1/g' /etc/locale.gen
44-
RUN locale-gen en_US
44+
RUN sed -i 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/g' /etc/locale.gen
45+
RUN sed -i 's/# de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/g' /etc/locale.gen
46+
RUN locale-gen
4547

4648
# set locale to utf-8
47-
RUN locale-gen en_US.UTF-8
49+
# RUN locale-gen en_US.UTF-8
4850
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'
4951

5052
# install coveralls (upgrade both pip and requests first)
@@ -65,6 +67,10 @@ RUN /bin/bash -c "./packagize.sh"
6567
RUN echo "; priority=20\nextension=sqlsrv.so\n" > /etc/php/7.3/mods-available/sqlsrv.ini
6668
RUN echo "; priority=30\nextension=pdo_sqlsrv.so\n" > /etc/php/7.3/mods-available/pdo_sqlsrv.ini
6769

70+
# create a writable ini file for testing locales
71+
RUN echo '' > `php --ini | grep "Scan for additional .ini files" | sed -e "s|.*:\s*||"`/99-overrides.ini
72+
RUN chmod 666 `php --ini | grep "Scan for additional .ini files" | sed -e "s|.*:\s*||"`/99-overrides.ini
73+
6874
WORKDIR $PHPSQLDIR/source/sqlsrv
6975
RUN /usr/bin/phpize && ./configure LDFLAGS="-lgcov" CXXFLAGS="-O0 --coverage" && make && make install
7076

azure-pipelines.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,9 @@ jobs:
107107
108108
- script: |
109109
sudo sed -i 's/# en_US ISO-8859-1/en_US ISO-8859-1/g' /etc/locale.gen
110-
sudo locale-gen en_US
111-
sudo locale-gen en_US.UTF-8
110+
sudo sed -i 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/g' /etc/locale.gen
111+
sudo sed -i 's/# de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/g' /etc/locale.gen
112+
sudo locale-gen
112113
export LANG='en_US.UTF-8'
113114
export LANGUAGE='en_US:en'
114115
export LC_ALL='en_US.UTF-8'
@@ -151,6 +152,9 @@ jobs:
151152
echo copying pdo_sqlsrv to $dest
152153
sudo cp 30-pdo_sqlsrv.ini $dest
153154
155+
sudo touch $dest/99-overrides.ini
156+
sudo chmod 666 $dest/99-overrides.ini
157+
154158
php --ri sqlsrv
155159
php --ri pdo_sqlsrv
156160
displayName: 'Build and install drivers'
@@ -162,6 +166,7 @@ jobs:
162166
sed -i -e 's/TARGET_USERNAME/'"$(uid)"'/g' MsSetup.inc
163167
sed -i -e 's/TARGET_PASSWORD/'"$(pwd)"'/g' MsSetup.inc
164168
169+
export LC_ALL='en_US.UTF-8'
165170
php run-tests.php -P ./*.phpt 2>&1 | tee ../sqlsrv.log
166171
displayName: 'Run sqlsrv functional tests'
167172
@@ -172,6 +177,7 @@ jobs:
172177
sed -i -e 's/TARGET_USERNAME/'"$(uid)"'/g' MsSetup.inc
173178
sed -i -e 's/TARGET_PASSWORD/'"$(pwd)"'/g' MsSetup.inc
174179
180+
export LC_ALL='en_US.UTF-8'
175181
php run-tests.php -P ./*.phpt 2>&1 | tee ../pdo_sqlsrv.log
176182
displayName: 'Run pdo_sqlsrv functional tests'
177183

source/pdo_sqlsrv/pdo_init.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,22 @@ PHP_RINIT_FUNCTION(pdo_sqlsrv)
220220
ZEND_TSRMLS_CACHE_UPDATE();
221221
#endif
222222

223+
#ifndef _WIN32
224+
// if necessary, set locale from the environment for ODBC, which MUST be done before any connection
225+
int set_locale = PDO_SQLSRV_G(set_locale_info);
226+
if (set_locale == 2) {
227+
setlocale(LC_ALL, "");
228+
LOG(SEV_NOTICE, "pdo_sqlsrv: setlocale LC_ALL");
229+
}
230+
else if (set_locale == 1) {
231+
setlocale(LC_CTYPE, "");
232+
LOG(SEV_NOTICE, "pdo_sqlsrv: setlocale LC_CTYPE");
233+
}
234+
else {
235+
LOG(SEV_NOTICE, "pdo_sqlsrv: setlocale NONE");
236+
}
237+
#endif
238+
223239
LOG( SEV_NOTICE, "pdo_sqlsrv: entering rinit" );
224240

225241
return SUCCESS;

source/pdo_sqlsrv/php_pdo_sqlsrv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ ZEND_BEGIN_MODULE_GLOBALS(pdo_sqlsrv)
3232
unsigned int log_severity;
3333
zend_long client_buffer_max_size;
3434

35+
#ifndef _WIN32
36+
zend_long set_locale_info;
37+
#endif
38+
3539
ZEND_END_MODULE_GLOBALS(pdo_sqlsrv)
3640

3741
ZEND_EXTERN_MODULE_GLOBALS(pdo_sqlsrv);

source/pdo_sqlsrv/php_pdo_sqlsrv_int.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,19 @@ extern HMODULE g_sqlsrv_hmodule;
5555
#define INI_PDO_SQLSRV_LOG "log_severity"
5656
#define INI_PREFIX "pdo_sqlsrv."
5757

58+
#ifndef _WIN32
59+
#define INI_PDO_SET_LOCALE_INFO "set_locale_info"
60+
#endif
61+
5862
PHP_INI_BEGIN()
5963
STD_PHP_INI_ENTRY( INI_PREFIX INI_PDO_SQLSRV_LOG , "0", PHP_INI_ALL, OnUpdateLong, log_severity,
6064
zend_pdo_sqlsrv_globals, pdo_sqlsrv_globals )
6165
STD_PHP_INI_ENTRY( INI_PREFIX INI_PDO_SQLSRV_CLIENT_BUFFER_MAX_SIZE , INI_BUFFERED_QUERY_LIMIT_DEFAULT, PHP_INI_ALL, OnUpdateLong,
6266
client_buffer_max_size, zend_pdo_sqlsrv_globals, pdo_sqlsrv_globals )
67+
#ifndef _WIN32
68+
STD_PHP_INI_ENTRY(INI_PREFIX INI_PDO_SET_LOCALE_INFO, "2", PHP_INI_ALL, OnUpdateLong, set_locale_info,
69+
zend_pdo_sqlsrv_globals, pdo_sqlsrv_globals)
70+
#endif
6371
PHP_INI_END()
6472

6573

source/shared/core_init.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,6 @@ void core_sqlsrv_minit( _Outptr_ sqlsrv_context** henv_cp, _Inout_ sqlsrv_contex
3939
SQLSRV_STATIC_ASSERT( sizeof( sqlsrv_sqltype ) == sizeof( zend_long ) );
4040
SQLSRV_STATIC_ASSERT( sizeof( sqlsrv_phptype ) == sizeof( zend_long ));
4141

42-
#ifndef _WIN32
43-
// set locale from environment
44-
// this is necessary for ODBC and MUST be done before connection
45-
setlocale(LC_ALL, "");
46-
#endif
47-
4842
*henv_cp = *henv_ncp = SQL_NULL_HANDLE; // initialize return values to NULL
4943

5044
try {

source/sqlsrv/init.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,25 @@ PHP_RINIT_FUNCTION(sqlsrv)
654654
SQLSRV_G( log_subsystems ) = INI_INT( subsystems );
655655
SQLSRV_G( buffered_query_limit ) = INI_INT( buffered_limit );
656656

657+
#ifndef _WIN32
658+
char set_locale_info[] = INI_PREFIX INI_SET_LOCALE_INFO;
659+
SQLSRV_G(set_locale_info) = INI_INT(set_locale_info);
660+
661+
// if necessary, set locale from the environment for ODBC, which MUST be done before any connection
662+
int set_locale = SQLSRV_G(set_locale_info);
663+
if (set_locale == 2) {
664+
setlocale(LC_ALL, "");
665+
}
666+
else if (set_locale == 1) {
667+
setlocale(LC_CTYPE, "");
668+
}
669+
else {
670+
// Do nothing
671+
}
672+
673+
LOG(SEV_NOTICE, INI_PREFIX INI_SET_LOCALE_INFO " = %1!d!", set_locale);
674+
#endif
675+
657676
LOG( SEV_NOTICE, INI_PREFIX INI_WARNINGS_RETURN_AS_ERRORS " = %1!s!", SQLSRV_G( warnings_return_as_errors ) ? "On" : "Off");
658677
LOG( SEV_NOTICE, INI_PREFIX INI_LOG_SEVERITY " = %1!d!", SQLSRV_G( log_severity ));
659678
LOG( SEV_NOTICE, INI_PREFIX INI_LOG_SUBSYSTEMS " = %1!d!", SQLSRV_G( log_subsystems ));

source/sqlsrv/php_sqlsrv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ zend_long current_subsystem;
4242
zend_bool warnings_return_as_errors;
4343
zend_long buffered_query_limit;
4444

45+
#ifndef _WIN32
46+
zend_long set_locale_info;
47+
#endif
48+
4549
ZEND_END_MODULE_GLOBALS(sqlsrv)
4650

4751
ZEND_EXTERN_MODULE_GLOBALS(sqlsrv);

source/sqlsrv/php_sqlsrv_int.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@
3737
#define INI_BUFFERED_QUERY_LIMIT "ClientBufferMaxKBSize"
3838
#define INI_PREFIX "sqlsrv."
3939

40+
#ifndef _WIN32
41+
#define INI_SET_LOCALE_INFO "SetLocaleInfo"
42+
#endif
43+
4044
PHP_INI_BEGIN()
4145
STD_PHP_INI_BOOLEAN( INI_PREFIX INI_WARNINGS_RETURN_AS_ERRORS , "1", PHP_INI_ALL, OnUpdateBool, warnings_return_as_errors,
4246
zend_sqlsrv_globals, sqlsrv_globals )
@@ -46,6 +50,11 @@ PHP_INI_BEGIN()
4650
sqlsrv_globals )
4751
STD_PHP_INI_ENTRY( INI_PREFIX INI_BUFFERED_QUERY_LIMIT, INI_BUFFERED_QUERY_LIMIT_DEFAULT, PHP_INI_ALL, OnUpdateLong, buffered_query_limit,
4852
zend_sqlsrv_globals, sqlsrv_globals )
53+
#ifndef _WIN32
54+
STD_PHP_INI_ENTRY(INI_PREFIX INI_SET_LOCALE_INFO, "2", PHP_INI_ALL, OnUpdateLong, set_locale_info,
55+
zend_sqlsrv_globals, sqlsrv_globals)
56+
#endif
57+
4958
PHP_INI_END()
5059

5160

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
--TEST--
2+
GitHub issue 1063 - make setting locale info configurable
3+
--DESCRIPTION--
4+
This test verifies that the users can configure using ini file to set application locale using the system locale or not. This test is valid for Linux and macOS systems only.
5+
--ENV--
6+
PHPT_EXEC=true
7+
--SKIPIF--
8+
<?php require('skipif_unix_locales.inc'); ?>
9+
--FILE--
10+
<?php
11+
function runTest($val, $file, $locale)
12+
{
13+
print("\n***sqlsrv.SetLocaleInfo = $val\npdo_sqlsrv.set_locale_info = $val***\n\n");
14+
shell_exec("echo 'sqlsrv.SetLocaleInfo = $val\npdo_sqlsrv.set_locale_info = $val' > $file");
15+
print_r(shell_exec(PHP_BINARY." ".dirname(__FILE__)."/pdo_1063_test_locale.php "));
16+
print_r(shell_exec(PHP_BINARY." ".dirname(__FILE__)."/pdo_1063_test_locale.php $locale"));
17+
}
18+
19+
$inifile = PHP_CONFIG_FILE_SCAN_DIR."/99-overrides.ini";
20+
21+
$locale1 = strtoupper(PHP_OS) === 'LINUX' ? "en_US.ISO-8859-1" : "en_US.ISO8859-1";
22+
$locale2 = 'de_DE.UTF-8';
23+
24+
runTest(0, $inifile, $locale1);
25+
runTest(1, $inifile, $locale2);
26+
runTest(2, $inifile, $locale2);
27+
?>
28+
--EXPECT--
29+
30+
***sqlsrv.SetLocaleInfo = 0
31+
pdo_sqlsrv.set_locale_info = 0***
32+
33+
**Begin**
34+
Current LC_MONETARY: C
35+
Current LC_CTYPE: en_US.UTF-8
36+
Currency symbol:
37+
Thousands_sep:
38+
Amount formatted: 10000.99
39+
Friday
40+
December
41+
3.14159
42+
**End**
43+
**Begin**
44+
Current LC_MONETARY: C
45+
Current LC_CTYPE: en_US.UTF-8
46+
Setting LC_ALL: en_US.ISO-8859-1
47+
Currency symbol: $
48+
Thousands_sep: ,
49+
Amount formatted: USD 10,000.99
50+
Friday
51+
December
52+
3.14159
53+
**End**
54+
55+
***sqlsrv.SetLocaleInfo = 1
56+
pdo_sqlsrv.set_locale_info = 1***
57+
58+
**Begin**
59+
Current LC_MONETARY: C
60+
Current LC_CTYPE: en_US.UTF-8
61+
Currency symbol:
62+
Thousands_sep:
63+
Amount formatted: 10000.99
64+
Friday
65+
December
66+
3.14159
67+
**End**
68+
**Begin**
69+
Current LC_MONETARY: C
70+
Current LC_CTYPE: en_US.UTF-8
71+
Setting LC_ALL: de_DE.UTF-8
72+
Currency symbol: €
73+
Thousands_sep: .
74+
Amount formatted: 10.000,99 EUR
75+
Freitag
76+
Dezember
77+
3,14159
78+
**End**
79+
80+
***sqlsrv.SetLocaleInfo = 2
81+
pdo_sqlsrv.set_locale_info = 2***
82+
83+
**Begin**
84+
Current LC_MONETARY: en_US.UTF-8
85+
Current LC_CTYPE: en_US.UTF-8
86+
Currency symbol: $
87+
Thousands_sep: ,
88+
Amount formatted: USD 10,000.99
89+
Friday
90+
December
91+
3.14159
92+
**End**
93+
**Begin**
94+
Current LC_MONETARY: en_US.UTF-8
95+
Current LC_CTYPE: en_US.UTF-8
96+
Setting LC_ALL: de_DE.UTF-8
97+
Currency symbol: €
98+
Thousands_sep: .
99+
Amount formatted: 10.000,99 EUR
100+
Freitag
101+
Dezember
102+
3,14159
103+
**End**

0 commit comments

Comments
 (0)