2012-06-14 3 views
4

Я анализирую XML с помощью simplexml_load_string() и используя данные в нем для обновления объектов Active Directory (AD) через LDAP.Иностранные символы и LDAP. Какую кодировку/кодировку ожидает LDAP?

Пример XML (упрощенный):

<?xml version="1.0" encoding="UTF-8"?> 
<users> 
    <user>Bìlbö Bággįnš</user> 
    <user>Gãńdåłf Thê Gręât</user> 
    <user>Śām Wīšë</user> 
</users> 

я во-первых, запустить ldap_search(), чтобы найти одного пользователя, а затем перейти к изменить свои атрибуты. Перекачка вышеуказанных значений прямо в AD с использованием LDAP приведет к появлению некоторых довольно искаженных символов.

Например: Bìlbö BággįnÅ¡

Я попытался следующие функции, но безрезультатно:

utf8_encode($str); 
utf8_decode($str); 
iconv("UTF-8", "ISO-8859-1//TRANSLIT", $str); 
iconv("UTF-8", "ASCII//TRANSLIT", $str); 
iconv("UTF-8", "T.61", $str); 

В идеале, я не хочу делать какие-либо из этих строк преобразования. UTF-8 должен быть в порядке, верно ?!

Я также заметил следующее: Я распечатал значения, чтобы посмотреть, как они выходят. скручивание скрипта в CLI покажет правильные символы, но веб-браузеры показывают то же, что и AD.

Что происходит? Должен ли я смотреть на что-то другое, например. Кодирование URL? Я надеюсь, что это до простой ошибки на моем конце.

EDIT: Я ввел эти символы, используя графический интерфейс AD admin, чтобы посмотреть, как они выйдут. Я могу читать их через LDAP. Правильные символы отображаются в браузере. зависание через CLI покажет вопросительные знаки вместо иностранных символов. Передача одного из этих возвращенных значений в mb_detect_encoding() вернет UTF-8.

Я решил немедленно изменить один и тот же объект, не записывая в новую строку, а просто изменяя существующее значение и сохраняя объект. Это прекрасно работает - я вижу правильное значение (обратное) в AD.

  • Разработка на Mac OS X 10.7 Lion - PHP 5.4.3
  • Запуск производства на: Red Hat 6 - PHP 5.4.3
  • AD сервера: Windows 2003

UPDATE: Через несколько месяцев я не смог найти ответ/решение этой проблемы. В конце концов, я пошел с заменой символов на их неадресный эквивалент (НЕ идеальный, я знаю).

+0

Используйте 'BIN2HEX()' на одном из этих значений, чтобы показать нам значения двоичной строки. – deceze

+0

@deceze 'bin2hex (á) == c3a1'. Я не уверен, что с персонажем что-то происходит, поскольку оно копируется и наклеивается повсюду. Системный буфер обмена может испортить/изменить его (?). – OmidTahouri

+0

Я предполагаю, что LDAP/AD, являющийся версией LDAP для Microsoft, находится в кодировке WINDOWS-1250 как что-либо от Microsoft ... Поэтому 'iconv (« UTF-8 »,« WINDOWS-1250 », $ str); должно сработать. – shadyyx

ответ

6

Вы используете LDAP v3?

ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3); 

LDAPv3 поддерживает UTF-8 по умолчанию, что он ожидает запросов и ответов, чтобы быть в по умолчанию.Смотрите здесь: http://technet.microsoft.com/en-us/library/cc961766.aspx

+0

Да, у меня есть этот комплект. – OmidTahouri

+0

Вы используете сценарий LDAP в поле NIX или в окне Windows. Это тот же сервер, на котором настроен AD? Какая версия PHP? –

+0

Попытка: 'iconv (« UTF-8 »,« T.61 », $ str);' –

1

Я сумел добавить внешние символы в LDAP два этапа:

  • добавить пользователя только с ASCII-символов (Iconv "ASCII // транслит")

  • использовать ldapmodify для обновления поля (ы) с UTF-8 символов

LDAPv3 является UTF-8, но инструмент, который я использовал (от smbldap-tools) не имел дело с этим должным образом.

0

Еще одна вещь, чтобы отметить для тех, кто наткнуться на это:

Если текст уже в UTF-8, то не пытайтесь повторно закодировать его. Обратите внимание на следующие примечания на странице документа для utf8_encode. Повторное кодирование уже закодированной строки приведет к искажению текста. Кроме того, функция допускает только одну конкретную кодировку для другой.

Вы можете легко проверить, если вам нужно UTF-8 закодировать строку, делая что-то вроде:

if (!preg_match('//u', $value)) { 
    // do your encoding process... 
} 

Что касается персонажей, не показывая правильно на веб-странице либо, но они находятся на CLI, сделать что вы устанавливаете правильную кодировку в заголовках:

header('Content-type: text/html; charset=utf-8');

0

Вот решение, которое работает для меня. Выполните следующие действия:

1.) Сначала убедитесь, что вы используете протокол LDAP версии 3, который использует «UTF-8» по умолчанию:

ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3); 

2.) Если вы хотите изменить пароль пользователя , убедитесь, что опция «Использовать TLS» установлена ​​в true и использует SSL для false.

ldap_start_tls($ldapConnection); 

3.) Я использовал номер порта 389.

4.) Используйте функцию PHP ldap_mod_replace для замены пароля пользователя.

5.) Используйте следующую функцию, чтобы закодировать ваш $password:

public function encodePassword($password) 
{ 
    $password="\"".$password."\""; 
    $encoded=""; 
    for ($i=0; $i <strlen($password); $i++){ 
     $encoded.="{$password{$i}}\000"; 
    } 
    return $encoded; 
} 

6.) Используйте следующую логику для изменения пароля пользователя:

$password="test"; 
if(mb_detect_encoding($password) == 'UTF-8') 
{ 
    $password = utf8_decode($password); 
} 

$add=array(); 
$add["unicodePwd"][0] = encodePassword($password); 

$result = @ldap_mod_replace($ldapConnection, $userDn, $add); 
if ($result === false){ 
    //your action 
} 
else{ 
    //Your action 
} 

7.) Обратите внимание, что функция encodePassword будет кодировать ваш $password в кодировку UTF-8. Если ваш пароль закодирован в UTF-8, , вы должны его декодировать перед отправкой его в функцию encodePassword.Вот почему я написал строку:

if(mb_detect_encoding($password) == 'UTF-8') 
{ 
    $password = utf8_decode($password); 
} 

Этот код работает для меня, когда я обеспечиваю немецкие умляуты в пароле: äüößÄÜ и т.д. ...

Смежные вопросы