# drush ev 'echo iconv("utf8", "ASCII//TRANSLIT", " héllô") . "\n";'
h?ll?
# php -r 'echo iconv("utf8", "ASCII//TRANSLIT", " héllô");'
hello
I find this difference very dangerous and would like to have a clear sight of what's happening here.
First I used ini_get_all() to compare settings between drush (Drupal bootstrap) and php, about localization :
After inserting in my cli/php.ini:
# mbstring.language = uni
the following shell snippet:
for func in mb_get_info iconv_get_encoding localeconv; do
diff <(php -r "var_dump($func());") <(drush ev "var_dump($func());")
donereturned no output...
good sign, the settings are the same and, except iconv_get_encoding() whose value are set to ISO-8859-1, all others are those of an UTF-8 setup.
(standard Squeeze fr.FR_UTF-8, php5-cli 5.3.3-7+squeeze3)
I don't have anything special in my .drush directory. Which settings are left to test in order to spot this annoying inconsistency ?
[ NB: I had to assign a version number ]
Comments
Comment #1
drzraf commentedOne bug was in my configuration for sure :
inserting the word "déchet" (é = uC3A9 <=> e9 in iso8859-1) :
browser:
Accept-Charset: utf-8,*mysql<<<"show create table taxonomy_term_data;"=>ENGINE=InnoDB CHARSET=utf8/taxonomy/term/3/edit, POSTEDname=d%C3%A9chetsmysql -N <<<"select name from taxonomy_term_data where tid = 3;"|xxd=> 64e9 6368 6574 730atracked it down to :
show create database <db>=>DEFAULT CHARACTER SET latin1[ but I still have to find why the drush ev and php commands above differ ]
I would close it, but I strongly think that the DB charset check should be done by the installer (even pecl uploadprogress is checked for its usability).
Or an admin may agree on this and reassign to Core / Locale / installer ?
Comment #2
greg.1.anderson commentedSearching the issue queue seems to be broken on drupal.org right now (?), but I would recommend searching for iconv in the Drush queue. There may be an older issue that could offer some insight as to what Drush is doing vis-a-vis character encodings, and why.
Comment #3
greg.1.anderson commentedSearching working again -- no issues with 'iconv', but I think there was an old issue that might be interesting, if you can find it.Comment #4
greg.1.anderson commentedThe issue I was thinking of was #797700: Convert drush output to terminal console code page, but not sure that explains the output shown in #0 above.
Comment #5
drzraf commentedI don't think the case in the original subject has to do with the terminal encoding:
both :
echo -n "héllô"|xxd -psphp -r 'echo "héllô";'|xxd -psdrush ev 'echo "héllô";'|xxd -psprint:
68c3a96c6cc3b4
but ...
I missed to say that my test with drush were done with specifying an alias (eg:
drush @beta ev ...)and I just found that when using my default database (which has the same settings), it works (iconv/translit prints "hello" as it should) !
(my @beta alias only contains the 'root' and 'uri' parameters)
I'll dig this further (but could it be related to aliases handling ?)
Comment #6
jdonson commentedTrying to clarify issues from database side below....
My apologies if I am missing the point.
Note that there are several layers of character set and collation encoding in mysql.
server default
schema default
table definition
connection
client settings
Try this and note that each can be configured statically and dynamically, as per version of mysqld:
mysql> show variables like '%char%';
+--------------------------+--------------------------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /Applications/MAMP/Library/share/mysql/charsets/ |
+--------------------------+--------------------------------------------------+
8 rows in set (0.00 sec)
mysql> show variables like '%collat%';
+----------------------+-------------------+
| Variable_name | Value |
+----------------------+-------------------+
| collation_connection | latin1_swedish_ci |
| collation_database | latin1_swedish_ci |
| collation_server | latin1_swedish_ci |
+----------------------+-------------------+
3 rows in set (0.00 sec)
Comment #7
drzraf commentedI've exactly the same setup, except
/usr/share/mysql/charsets/ascharacter_sets_dir:)Comment #8
kotnik commentedIf you do it outside Drupal (hence without Drupal bootstrap) you get correct output:
Will check what in boostrap makes it behave this way.
Comment #9
greg.1.anderson commentedI predict that whatever it is that is affecting encoding will be found in the Drupal bootstrap code. Best of luck in your isolation efforts.
Comment #10
drzraf commentedthanks !
I'm still not able to reproduce this by tweaking different directory (will try later)
but I bissected bootstrap.inc down to the "faulty" line which is... obviously :
setlocale(LC_ALL, 'C');, l. 698 inincludes/bootstrap.inc[ removed it and it works as it should ]
So why is this line here in the first place. LC_COLLATE=C would make sense in order to fix glob([a-Z]*) problems
but I don't understand its use for LC_ALL.
Back to 33c7e4da it was done in order fix #614124: Bootstrap should reset locale settings
But a setlocale(LC_CTYPE) happened to be into
include/unicode.incback from 11a4aba9 (2005) to fix #26688: Add mbstring support to Drupalbut LC_CTYPE would *also* have affected iconv in such case (LC_COLLATE wouldn't)
#614124: Bootstrap should reset locale settings is still opened and unassigned... so no need to reopen...
but still have to understand how it's related to the use of aliases or root directory.
Comment #11
damien tournoud commentedDrupal should not respect the locale settings of the server. Especially, the very important part is
LC_NUMERIC=Cbecause otherwise PHP formats floats in a locale-dependent fashion.Respecting the locale settings of the shell might be in the scope of Drush, but it's not in the scope of Drupal.
Comment #12
greg.1.anderson commentedIf Drupal does a
setlocale(LC_ALL, 'C');, it seems that it would be undesirable for Drush to undo that, unless, perhaps it could do a save/set/restore locale setting around actual output in drush_print & c.This returns us to #0, which shows the symptoms but not the use case.
The data that is being "incorrectly" transliterated was provided from the cli in the encoding expected for the system. This is different than data coming from the Drupal database being incorrectly interpreted. Perhaps you need to iconv to UTF8 your data before you pass it to Drush. Alternately, perhaps Drush needs to iconv the cli parameters prior to bootstrapping Drupal. And what about drushrc.php option values; do they need to be transliterated as well?Edit: Input data is indeed UTF8; the problem here is not in the encoding of the input data, but the way that setting the locale to 'C' affects the output transliteration of iconv.
Comment #13
drzraf commentedThe fact that it comes from the CLI, a DB, a file, ... does not really matter as long
as we ensure it is valid UTF-8. For example, the problem also happens with :
echo t( iconv( "utf8", "ASCII//TRANSLIT", system("echo \"héllô\";" ) ) )(you may also
touch /tmp/héllô && iconv ( system( "ls /tmp" ) );)The problem is in the way the core resets the whole locale thus making
locale-dependant functions (like iconv()) fail. The issue probably also affect modules
which handles files / lists directories.
Comment #14
greg.1.anderson commentedYes, you may very well be right, but there is nothing Drush can do about the locale setting after the Drupal bootstrap. If you have code in your drush module that needs to operate under a particular locale, you could call setlocale yourself immediately prior to the i18n calls; however, you'd need to set it back again when you were done, or you'd risk breaking Drupal's expected behavior.
I think we have no choice but to close this issue as 'works as designed'.
Comment #15
drzraf commentedI agree on closing this issue.
about the "DB charset check" from #1 I'll see if it's worth opening an issue.
About the
drush @beta evvsdrush evI'm not able to reproduce a difference.(both print "h?ll?").
Anyway, there's still the strange behavior experimented by kotnik where the output depends
on the directory it's run from.
Could the execution of
includes/bootstrap.incdrupal_environment_initialize()be related in some way to the directory drush is run into ? I don't know.
Comment #16
greg.1.anderson commentedDrush will attempt to find a Drupal site at the cwd, so whether or not Drupal is bootstrapped can indeed depend on where drush is executed from.
Comment #16.0
greg.1.anderson commentedstyle