Пролог и кодировка php

Я создаю интерфейс между swi-prolog и php. PHP пишет команды, которые он хочет, чтобы пролог запускал в файле, а затем выполняет системный вызов, поэтому пролог запускает файл. Проблема в том, что когда в файле есть специальные символы (например, á, í, ã, ê и т. д.), эти символы заменяются на � в выводе пролога, я знаю, что этот код для неизвестные/неопознанные кодовые точки, но мне не удалось решить проблему, с которой Я нашел в Интернете. Если запустить файл из терминала самостоятельно, он показывает правильные символы, просто когда 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.

Кто-нибудь знает, как заставить его правильно интерпретировать строку?


person Vitor Paisante    schedule 05.07.2012    source источник
comment
помимо того факта, что вы должны экранировать кавычки в своих переменных, где персонажи, о которых вы говорите, появляются на сцене? А вы проверяли совпадение всех кодировок (терминала, IDE и т.д.)?   -  person Walter Tross    schedule 06.07.2012


Ответы (1)


Скорее всего, Prolog ожидает символы в кодировке UTF-8, а вы передаете его ISO-8859-n символов, где n, скорее всего, равно 1 или 15. В UTF-8, когда байт >= 128 виден, это либо первый из многобайтовой последовательности (если он >= 192), либо байт продолжения. Если за первым байтом многобайтовой последовательности не следует байт продолжения или если последовательность начинается с байта продолжения, вы получаете нераспознанную последовательность байтов, в вашем случае кодовая точка U+FFFD. Все символы с диакритическими знаками выше 128 в ISO-8859-n.

Посмотрите также справочную страницу swi-prolog по кодированию, особенно весь абзац, начинающийся с эти две фразы:

Кодировка по умолчанию для файлов получена из флага Пролога encoding, который инициализируется из среды. Если переменная среды LANG оканчивается на «UTF-8», предполагается эта кодировка.

Хорошей причиной различного поведения swi-prolog при вызове из оболочки или из PHP может быть разная установка переменной окружения LANG в этих двух случаях. Но в этом же пункте инструкции упоминаются способы принудительной кодировки.

В оболочке самый быстрый способ увидеть байты, содержащиеся в файле, - это выполнить od -tx1z filename | less (пропустить z в случае труднопечатаемых символов).

person Walter Tross    schedule 05.07.2012