6

我正在使用 解析 XML,simplexml_load_string()并使用其中的数据通过 LDAP 更新 Active Directory (AD) 对象。

示例 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>

我首先运行 anldap_search()来查找单个用户,然后继续更改他们的属性。使用 LDAP 将上述值直接输入 AD 会导致出现一些非常混乱的字符。

例如: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 中卷曲脚本将显示正确的字符,但 Web 浏览器显示与 AD 相同。

这是怎么回事?我应该看别的东西吗,例如。网址编码? 我希望这归结为我的一个简单错误。

编辑: 我使用 AD 管理 GUI 输入了这些字符,看看它们会如何出现。我可以通过 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
  • 广告服务器:Windows 2003

更新: 几个月后,我找不到这个问题的答案/解决方案。最后,我将字符替换为它们的非重音等价物(我知道,这并不理想)。

4

4 回答 4

8

您使用的是 LDAP v3 吗?

ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);

LDAPv3 默认支持 UTF-8,它希望请求和响应默认使用。见这里:http ://technet.microsoft.com/en-us/library/cc961766.aspx

于 2012-06-14T17:45:26.183 回答
2

这是对我有用的解决方案。做以下事情:

1.) 首先确保您使用的是默认使用“UTF-8”的 LDAP 协议版本 3:

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);
}

当我在密码中提供德语变音符号时,此代码对我有用:äüößÄÜ等等...

于 2016-12-09T12:50:07.550 回答
1

我已经设法通过两个步骤在 LDAP 中添加外来字符:

  • 仅使用 ASCII 字符添加用户 (iconv "ASCII//TRANSLIT")

  • 用于使用ldapmodifyUTF-8 字符更新字段

LDAPv3 是 UTF-8,但我使用的工具(来自smbldap-tools)没有正确处理它。

于 2016-08-24T13:43:13.087 回答
1

对于那些偶然发现这一点的人来说,还有一件事要提:

如果您的文本已经是 UTF-8,那么不要尝试重新编码它。请注意utf8_encode文档页面上的以下注释。重新编码已经编码的字符串会导致文本乱码。此外,该功能仅允许将一种特定编码转换为另一种。

您可以通过执行以下操作轻松测试是否需要对字符串进行 UTF-8 编码:

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

关于网页上未正确显示的字符,但它们在 CLI 上,请确保您在标题中设置了正确的字符集:

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

于 2016-08-24T14:36:23.333 回答