我做了几个相关的主题,但这是我正在寻找答案的直接问题。如果php版本为5,我的框架将使用Zend_Translate
,否则我必须模仿4的功能。
似乎几乎gettext的每个实现都依赖于setlocale或locales,我知道系统之间存在很多不一致的原因,这就是为什么我不想依赖它。
我已尝试过几次让textdomain
,bindtextdomain
和gettext
函数正常工作,但我总是需要调用setlocale
。
顺便说一句,所有的.mo文件都是UTF-8。
答案 0 :(得分:2)
这里有一些可重用的代码,用于根据Zend_Translate_Adapter_Gettext
解析PHP中的MO文件:
<?php
class MoParser {
private $_bigEndian = false;
private $_file = false;
private $_data = array();
private function _readMOData($bytes)
{
if ($this->_bigEndian === false) {
return unpack('V' . $bytes, fread($this->_file, 4 * $bytes));
} else {
return unpack('N' . $bytes, fread($this->_file, 4 * $bytes));
}
}
public function loadTranslationData($filename, $locale)
{
$this->_data = array();
$this->_bigEndian = false;
$this->_file = @fopen($filename, 'rb');
if (!$this->_file) throw new Exception('Error opening translation file \'' . $filename . '\'.');
if (@filesize($filename) < 10) throw new Exception('\'' . $filename . '\' is not a gettext file');
// get Endian
$input = $this->_readMOData(1);
if (strtolower(substr(dechex($input[1]), -8)) == "950412de") {
$this->_bigEndian = false;
} else if (strtolower(substr(dechex($input[1]), -8)) == "de120495") {
$this->_bigEndian = true;
} else {
throw new Exception('\'' . $filename . '\' is not a gettext file');
}
// read revision - not supported for now
$input = $this->_readMOData(1);
// number of bytes
$input = $this->_readMOData(1);
$total = $input[1];
// number of original strings
$input = $this->_readMOData(1);
$OOffset = $input[1];
// number of translation strings
$input = $this->_readMOData(1);
$TOffset = $input[1];
// fill the original table
fseek($this->_file, $OOffset);
$origtemp = $this->_readMOData(2 * $total);
fseek($this->_file, $TOffset);
$transtemp = $this->_readMOData(2 * $total);
for($count = 0; $count < $total; ++$count) {
if ($origtemp[$count * 2 + 1] != 0) {
fseek($this->_file, $origtemp[$count * 2 + 2]);
$original = @fread($this->_file, $origtemp[$count * 2 + 1]);
$original = explode("\0", $original);
} else {
$original[0] = '';
}
if ($transtemp[$count * 2 + 1] != 0) {
fseek($this->_file, $transtemp[$count * 2 + 2]);
$translate = fread($this->_file, $transtemp[$count * 2 + 1]);
$translate = explode("\0", $translate);
if ((count($original) > 1) && (count($translate) > 1)) {
$this->_data[$locale][$original[0]] = $translate;
array_shift($original);
foreach ($original as $orig) {
$this->_data[$locale][$orig] = '';
}
} else {
$this->_data[$locale][$original[0]] = $translate[0];
}
}
}
$this->_data[$locale][''] = trim($this->_data[$locale]['']);
unset($this->_data[$locale]['']);
return $this->_data;
}
}
答案 1 :(得分:1)
好吧,我基本上最后编写了一个基于Zend的Gettext Adapter的mo文件解析器,据我所知gettext非常依赖于语言环境,因此手动解析.mo文件可以避免在奇怪情况下运行的麻烦与setlocale
的区域设置问题。我还计划解析以xml文件形式提供的Zend Locale数据。