我正在swi-prolog和php之间创建一个接口。php 编写它希望 prolog 在文件上运行的命令,然后执行系统调用,以便 prolog 运行该文件。问题是,当文件上有特殊字符(如 á、í、ã、ê 等)时,这些字符在 prolog 的输出中被 ''uFFFD 替换,我知道这个代码点是用于未知/未识别的代码点,但我没有成功解决我在互联网上找到的问题。如果自己从终端运行文件,它会显示正确的字符,就在 php 从 exec 运行时,shell_exec它似乎失去了原因。
这是使用的代码,首先是 php:
$arquivo = fopen("/home/giz/prologDB/run.pl", w);
$run = <<<EOT
go :-
consult('/home/giz/prologDB/pessoasOps.pl'),
addPessoa(0,'$name','$posicao','$resume','$unidade','$curso','$disciplina',$alunos,[]),
halt.
EOT;
echo $run;
fwrite($arquivo, $run);
$cmd = "prolog -f /home/giz/prologDB/run.pl -g go";
exec( $cmd, $output );
echo "'n";
print_r( $output );
echo "'n";
原日志代码:
addPessoa(LOCAL, NOME, POSICAO, RESUMO, UNIDADE, CURSO, DISCIPLINA, ALUNOS, REFERENCIA):-
write( 'Prolog 'nwas called 'nfrom PHP 'nsuccessfully.'n' ),
write('pessoa('),
write(LOCAL),
write(','''),
write(NOME),
write(''','''),
write(POSICAO),
write(''','''),
write(RESUMO),
write(''','''),
write(UNIDADE),
write(''','''),
write(CURSO),
write(''','''),
write(DISCIPLINA),
write(''','),
write(ALUNOS),
write(','),
write(REFERENCIA),
write(').'n'),
make.
有人知道如何让它正确解释字符串吗?
Prolog很可能需要UTF-8编码的字符,而你正在给它输入ISO-8859-n字符,其中n很可能是1或15。在 UTF-8 中,当看到一个字节>= 128 时,它要么是多字节序列中的第一个(如果是>= 192),要么是延续字节。如果多字节序列的第一个字节后跟没有延续字节,或者序列以延续字节开头,则会得到一个无法识别的字节序列,在本例中为 U+FFFD 代码点。在 ISO-8859-n 中,所有带有音调符号的字符都高于 128。
另请查看 swi-prolog 关于编码的手册页,尤其是以这两句话开头的整个段落:
文件的默认编码派生自 Prolog 标志
encoding
,它是从环境中初始化的。如果 环境变量 LANG 以"UTF-8"结尾,假定此编码。
从 shell 或 PHP 内部调用 swi-prolog 时,不同行为的一个很好的理由可能是在这两种情况下LANG
环境变量的不同设置。但在同一段中,手册提到了强制编码的方法。
在 shell 中,查看文件中包含的字节的最快方法是执行od -tx1z filename | less
(如果字符难以打印,则省略 z)。