sweetchuck / po-parser
GetText PO/POT file parser
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 4
pkg:composer/sweetchuck/po-parser
Requires
- php: >=8.4
- ext-json: *
- ext-mbstring: *
- ext-pcre: *
Requires (Dev)
- ext-dom: *
- nuvoleweb/robo-config: ^3.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^2.1
- phpstan/phpstan-phpunit: ^2.0
- phpunit/phpunit: ^12.0
- squizlabs/php_codesniffer: ^4.0
- sweetchuck/git-hooks: 2.x-dev
- sweetchuck/robo-git: 4.x-dev
- sweetchuck/robo-phpcs: 4.x-dev
- sweetchuck/robo-phpstan: 3.x-dev
- symfony/var-dumper: ^7.0
README
A PHP library for parsing and reading Gettext PO and POT files. Parse translations, headers, and message context from localization files programmatically.
Features
- Parse Gettext PO/POT files efficiently
- Read translation metadata and headers
- Support for pluralization forms
- Message context (msgctxt) support
- Multiline string handling
- Seekable file iteration for large files
- Memory-efficient streaming parser
Quick Start
use Sweetchuck\PoParser\PoReader; use Sweetchuck\PoParser\PoHeader; // Open a PO file. $fileHandler = fopen('translations.hu.po', 'r'); $reader = new PoReader(); $reader->setFileHandler($fileHandler); // Read and process all items. while ($reader->valid()) { $item = $reader->current(); echo $item->getMsgid(); echo $item->getMsgstr(); $reader->next(); } // Or read the header. $reader->seek(0); $headerItem = $reader->current(); $header = PoHeader::createFromItem($headerItem); echo $header->getProjectIdVersion();
Usage
Parsing Files
$fileHandler = fopen('path/to/file.po', 'r'); $reader = new PoReader(); $reader->setFileHandler($fileHandler); // Iterate through all messages $reader->rewind(); while ($reader->valid()) { $item = $reader->current(); // Process $item $reader->next(); }
Accessing Message Data
Each PoItem contains:
- getMsgid()- Original message string
- getMsgstr()- Translated message string(s)
- getMsgctxt()- Message context
- getMsgidPlural()- Plural form of the message
- getComments()- Associated comments
Working with Headers
$header = PoHeader::createFromItem($item); echo $header->getProjectIdVersion(); echo $header['Language']; echo $header['Content-Type']; // Iterate through all header fields foreach ($header as $key => $value) { echo "$key: $value"; }
Seeking to Specific Items
$reader->seek(5); $item = $reader->current();
Generating PO Files
You can create and manipulate PO file content programmatically:
use Sweetchuck\PoParser\PoComment; use Sweetchuck\PoParser\PoReader; use Sweetchuck\PoParser\PoHeader; use Sweetchuck\PoParser\PoItem; // Create a header item $header = new PoHeader(); $header->setProjectIdVersion('MyProject (1.0.0)'); // or $header['Project-Id-Version'] = 'MyProject (1.0.0)'; $header['Language'] = 'hu_HU'; $header['Content-Type'] = 'text/plain; charset=UTF-8'; $header['Plural-Forms'] = 'nplurals=2; plural=(n!=1);'; $item0 = PoItem::createFromHeader($header); // Create a simple message item. $item1 = PoItem::__set_state([ 'comments' => [ '# Translator comment', '#. Extracted comment about forms', '#: src/main.php:42', '#, fuzzy', '#, c-format', '#| msgid "Old Form"', '# Additional context line 1', '# Additional context line 2', ], 'msgid' => ['Forms'], 'msgstr' => ['' => ['Űrlapok']], ]); // Create a plural form item. $item2Comments = new PoComment(); $item2Comments->setFlag('range', '1..100'); $item2 = new PoItem(); $item2->comments = $item2Comments->toItemValue(); $item2->msgid = ['1 minute']; $item2->msgidPlural = ['@count minutes']; $item2->msgstr = [ 0 => ['1 perc'], 1 => ['@count perc'], ]; // Build file content. $content = ''; foreach ([$item0, $item1, $item2] as $item) { $content .= (string) $item; $content .= "\n"; }
This generates:
msgid ""
msgstr ""
"Project-Id-Version: MyProject (1.0.0)\n"
"Language: hu_HU\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
# Translator comment
#. Extracted comment about forms
#: src/main.php:42
#, fuzzy
#, c-format
#| msgid "Old Form"
# Additional context line 1
# Additional context line 2
msgid "Forms"
msgstr "Űrlapok"
#, range 1..100
msgid "1 minute"
msgid_plural "@count minutes"
msgstr[0] "1 perc"
msgstr[1] "@count perc"