Php 外来字符和LDAP。LDAP需要什么编码/字符集?

Php 外来字符和LDAP。LDAP需要什么编码/字符集?,php,encoding,active-directory,ldap,Php,Encoding,Active Directory,Ldap,我使用simplexml\u load\u string()解析XML,并使用其中的数据通过LDAP更新Active Directory(AD)对象 示例XML(简化): 理想情况下,我不想做任何这些字符串转换。UTF-8应该没问题吧 我还注意到以下几点: 我已经打印出了这些值,看看它们是如何出来的。在CLI中对脚本进行卷曲将显示正确的字符,但web浏览器显示的字符与AD相同 发生了什么事?我应该看看别的东西吗,比如URL编码? 我希望这是我这方面的一个简单错误 编辑: 我使用AD admin

我使用
simplexml\u load\u string()
解析XML,并使用其中的数据通过LDAP更新Active Directory(AD)对象

示例XML(简化):

理想情况下,我不想做任何这些字符串转换。UTF-8应该没问题吧

我还注意到以下几点: 我已经打印出了这些值,看看它们是如何出来的。在CLI中对脚本进行卷曲将显示正确的字符,但web浏览器显示的字符与AD相同

发生了什么事?我应该看看别的东西吗,比如URL编码? 我希望这是我这方面的一个简单错误

编辑: 我使用AD admin GUI输入了这些字符,以查看它们的效果。我可以通过LDAP阅读它们。在浏览器中显示正确的字符。通过CLI调用将显示问号,而不是外来字符。将这些返回值之一传递到
mb\u detect\u encoding()
将返回UTF-8

我决定立即修改同一个对象,不写入新字符串,而只是反转现有值并保存该对象。这工作正常-我在AD中看到正确的值(反转)

  • 在MacOSX10.7Lion-PHP5.4.3上开发
  • 在:Red Hat 6-PHP5.4.3上运行生产
  • 广告服务器:Windows 2003
更新: 几个月后,我找不到这个问题的答案/解决办法。 最后,我将字符替换为非重音的等效字符(我知道这并不理想)。

您使用的是LDAP v3吗

ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);

LDAPv3默认支持UTF-8,它希望请求和响应默认处于UTF-8中。请参见此处:

我通过两个步骤成功地在LDAP中添加了外来字符:

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

  • 使用
    ldapmodify
    以UTF-8字符更新字段


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

对于那些在这方面遇到障碍的人,还有一件事要提:

如果文本已经是UTF-8格式,则不要尝试对其重新编码。请注意文档页面上的以下备注。对已编码的字符串重新编码将导致文本乱码。此外,该函数只允许将一个特定编码转换为另一个特定编码

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

if (!preg_match('//u', $value)) {
    // do your encoding process...
}
对于网页上未正确显示但在CLI上的字符,请确保在标题中设置了正确的字符集:


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

这是一个适合我的解决方案。做以下事情:

1.)首先确保您使用的是使用 默认情况下为“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\u mod\u replace
替换用户密码

5.)使用以下功能对
$password
进行编码:

public function encodePassword($password)
{
    $password="\"".$password."\"";
    $encoded="";
    for ($i=0; $i <strlen($password); $i++){ 
        $encoded.="{$password{$i}}\000"; 
    }
    return $encoded;
}
7.)请注意,函数
encodePassword
将对您的密码进行编码
$password
到UTF-8编码。如果您的密码是UTF-8编码的, 然后,您必须在将其发送到服务器之前对其进行解码
encodePassword
功能。这就是我写这句话的原因:

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

当我在密码中提供德语Umlauts时,该代码对我起作用:
äüöß196;Ü
等。

对其中一个值使用
bin2hex()
来显示二进制字符串值。@deceze
bin2hex(á)=c3a1
。我不确定在复制和粘贴角色时,角色是否发生了任何变化。系统剪贴板可能会损坏/更改它(?)。我猜作为LDAP的Microsoft版本的LDAP/AD在
WINDOWS-1250
中编码为Microsoft的任何内容。。。因此,
iconv(“UTF-8”、“WINDOWS-1250”和$str)应该可以工作。它不喜欢WINDOWS-1250-
iconv():在输入字符串中检测到非法字符
这与php文件本身没有UTF8编码有关吗?访问ldap的php文件应将其编码类型设置为UTF-8?您是在NIX框还是Windows框上运行ldap脚本。它是配置AD的同一台服务器吗?什么版本的PHP?试试:
iconv(“UTF-8”、“T.61”、“$str”)好点;我已将要求的信息添加到问题中。。。和:
错误的字符集,不允许从“UTF-8”转换为“T.61”。
:(尝试
ldap_8859_to_t61()
ldap_t61_to_8859
。看看这是否允许您转换。这解决了我遇到的问题。它在手册中,但我查看了1000次。设置它完全解决了我的问题!!谢谢
public function encodePassword($password)
{
    $password="\"".$password."\"";
    $encoded="";
    for ($i=0; $i <strlen($password); $i++){ 
        $encoded.="{$password{$i}}\000"; 
    }
    return $encoded;
}
$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
}
if(mb_detect_encoding($password) == 'UTF-8')
{
    $password = utf8_decode($password);
}