get_browser() 返回 FALSE。

11

- 在Linux上运行PHP 5.3.8 -

首先,我们已经解决了这个问题,使函数返回了预期的值。然而,我还有很多未解答的问题,这个“解决方案”更像是一个hack而不是真正意义上的解决方案。

我花了一整天的时间来解决这个问题,所以请容忍我解释解决方法。首先,问题在于get_browser()的返回值是FALSE,这不是一个文档化的返回值。这让我认为,返回FALSE意味着函数内部出现了某种错误状态。

测试代码经过多次迭代后,变成了一个简单的var_dump(get_browser($agent, true))。我使用直接传递用户代理字符串和不传递任何参数的方式进行测试,例如var_dump(get_browser()),它们都返回相同的值。

尝试/验证以下操作,但返回值没有改变:

browscap.ini:

  • 拥有最新版本,也测试了几个之前的版本

权限:

  • bowscap.ini - 初始权限为644,但我尝试了从644到777的所有权限

  • 包含browscap.ini的目录 - 初始权限为755,也尝试了777

  • 使用其他函数如file()验证PHP可以访问文件和目录

用户代理

  • 尝试手动传递用户代理字符串

  • 尝试传递$_SERVER['HTTP_USER_AGENT']

  • 通过远方的朋友验证我的用户代理字符串 - get_browser()返回预期值。

php.ini

  • browscap设置指向正确的位置

  • 再次使用echo count(file(ini_get('browscap')));进行验证

  • 错误日志

    • 查看PHP和Apache错误日志,是否有'browscap'或任何相关的内容 - 没有异常情况。

    文件结构

    这就是我怀疑错误的来源。browscap.ini位于/var/php/中,具有适当的权限,如上所述。我的想法是,也许PHP无法访问此目录,或者类似这样的情况。但是,这个目录也是存储会话的位置,所以这变得不太可能。

    "解决方案"

    解决问题的方法是将browscap.ini移动到公共Web目录中。我很好奇为什么会这样,特别是考虑到未记录的返回值。"解决方案"有效,但并非我想找到的解决方案...

    get_browser()是否具有特殊的权限要求或类似的要求? file()可以轻松访问目录和文件,但get_browser()不能(可能)。我几乎因这个问题而抓狂了,希望能得到一些解决方案!

    谢谢阅读!


    1
    你使用这个功能是为了什么?用户代理头并不是非常可靠,因此识别它也不是很准确。你最好使用JavaScript测试浏览器的能力,并将这些信息发送到服务器,这样可能会更好一些。然而,这也不是必要的,因为通常你可以完全在客户端处理差异。 - dqhendricks
    @dqhendricks 这是针对(相当大的)现有代码库的维护。此调用返回的值在预处理和提供内容中都被广泛使用。我总是乐于尝试新的/更好的方法,但在当前状态下改变整个系统可能需要太多工作。 - orourkek
    我很好奇 phi.ini 中的 browsecap 值是什么。它是完整路径 /var/php/browsecap.ini 还是相对路径 browsecap.ini?或者在测试过程中你一直在更改它? - drew010
    @drew010 这是完整的路径,从未更改过,并且我多次验证了路径的准确性,通常使用代码:echo count(file(ini_get('browscap'))); 来进行验证,它返回了预期的结果。这意味着 file() 可以正常打开和读取文件,因此 get_browser() 也应该能够做到。 - orourkek
    @orourkek get_browser 会返回 false,原因可能是无法打开 ini 文件、内存分配失败或读取文件时出错。我怀疑由于某种原因它没有正确地打开文件。请参见此处的第 469-470 行(http://lxr.php.net/opengrok/xref/PHP_5_3/ext/standard/browscap.c#456)。 - drew010
    3个回答

    7

    您已经尝试了所有必需的方法。

    http://php.net/manual/en/function.get-browser.php 注意事项:

    为了使其正常工作,您在php.ini中的browscap配置设置必须指向系统上browscap.ini文件的正确位置。

    browscap.ini未捆绑在PHP中,但您可以在此处找到最新的php_browscap.ini文件。

    虽然browscap.ini包含许多浏览器的信息,但它依赖于用户更新以保持数据库当前。该文件的格式相当易于理解。


    解决问题的方法是将browscap.ini移动到公共网站目录中。 可能正在指向该位置,即公共网站目录。
    get_browser()有特殊权限要求或类似的东西吗? 只需要阅读权限。

    使用的browscap.ini是可用的最新版本。我还尝试了我们文件系统中拥有的多个先前版本。至于权限,PHP对文件和目录具有读取权限,我们甚至尝试了在两者上设置777权限。 - orourkek
    我的意思是说,在 php.ini 中有一个 browscap 设置,它实际上是该文件的路径。检查一下它指向哪个目录。 - Somnath Muluk

    4
    实际上,即使在手册页面上没有记录,get_browser函数也可能由于多种原因返回FALSE
    至少查看底层源代码可以让人这样假设。
    我建议您查看其中的内容,然后让我知道您是否有其他问题。那时我可能能够回答它们。

    1
    我已经查看了可能导致返回false的各种原因,但考虑到环境,它们都没有任何意义。我对错误的最佳猜测是读取/打开文件时出现了一些问题,我的具体问题与此理论有关,例如,如果file()可以访问该文件,为什么get_browser()不能?PHP使用许多函数打开、读取和写入此文件没有问题,除了get_browser(),由于未知原因而失败。 - orourkek

    4

    我和原帖作者遇到了完全相同的问题。解决办法是,php.ini需要一个绝对路径来指定browscap.ini文件。

    所以,尽管PHP找到了该文件并出现在phpinfo()的输出中,但以下行是问题所在:

    browscap = browscap.ini
    

    使用这行代码,getBrowser() 返回了 false

    然而,将其改为绝对路径就可以解决问题,像这样:

    browscap = /etc/browscap.ini
    

    希望这能有所帮助!这是一个奇怪的问题...


    有趣的是,这并不是我遇到问题的原因 - 我最初使用的是相对路径,但在调试过程中改为了绝对路径。然而,查看相关的源代码(http://lxr.php.net/xref/PHP_5_3/ext/standard/browscap.c#454)显示了一些地方返回了`FALSE`。 - orourkek

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接