2

为了在使用 PHP SimpleXML 时引用本地 DTD,我需要将绝对路径转换为文件类型 URI。例如,将 /home/sitename/www/xml/example.dtd 转换为 file:///home/sitename/www/xml/example.dtd。

在给出的示例中,这很容易,因为所需要的只是在路径前面添加“文件”方案。但是,如果出现诸如其中一个目录名称中有空格的情况,这还不够好。该机制应适用于 Windows 或 Linux,并允许目录名称中包含非 ASCII 字符。

到目前为止设计的代码是:

    $absparts = explode('/', _ALIRO_ABSOLUTE_PATH);
    $driveletter = (0 == strncasecmp(PHP_OS, 'win', 3)) ? array_shift($absparts) : '';
    $filename = $driveletter.implode('/', array_map('rawurlencode', $absparts)).'/xml/'.$filename.'.dtd';
    $href = 'file:///'.$filename;

其中定义的符号是系统根目录的绝对路径(总是带有正斜杠),DTD 位于 xml 子目录中,名称为 $filename,后跟扩展名 .dtd。

这会正常工作吗?有更好的方法吗?

让我再解释一下背景。目的是使用 SimpleXML 解析 XML 文档。这是使用带有 LIBXML_DTDVALID 选项的 simplexml_load_string() 函数完成的。XML 文档将包含一个指向主网站的真实 URI,但我不想引入与到达远方网站有关的延迟,或者用请求加载主网站。因此,对 DTD 的引用进行了编辑,以便引用本地机器。但它必须作为 URI 嵌入到 XML 文档中的 DOCTYPE 中。约束不是我的选择,它们隐含在 DOCTYPE 的规则中,并由 SimpleXML 函数强制执行。我可以将文件的位置确定为绝对路径,但要将其放入 DOCTYPE,必须将其转换为 URI。

4

3 回答 3

2

如果您在本地运行 PHP,则必须运行像 Apache 这样的服务器。那么为什么需要file://参考呢?只需使用常规参考。

如果您的脚本已打开,您可以在 HTMLhttp://localhost/index.php中引用该文件。/xml/example.dtd或者,如果您打算从 PHP 读取文件,请使用$_SERVER['DOCUMENT_ROOT'] . '/xml/example.dtd'

在这些情况下,相同的代码应该可以在您的本地计算机和实时服务器上正常工作。


好的,根据您澄清的问题,我有一个想法,您可能做的比您需要的要多。我不相信您需要检测 Windows,您只需要在文档根目录前加上前缀file://(并对 URL 进行编码)。换句话说,你最终会得到file://C:/My Documents...或者file:///home/site...

当然,您仍然可以使用 HTTP 引用而不是文件。就像我上面所说的,用户将在服务器上运行,因此您应该能够使用$_SERVER变量的各个部分(例如$_SERVER['HTTP_HOST'])来拼凑一个更具体的 URL。

于 2009-11-16T15:40:50.073 回答
1

你试过realpath吗?

于 2009-11-16T15:35:53.890 回答
0

你真的需要把它本地化吗?你不能在网络服务器上托管 dtd 吗?显然,这使它变得更容易,您无需担心转换。我认为您最好尝试托管它而不是处理操作系统差异。

于 2009-11-16T15:26:47.840 回答