Last updated: August 29, 2026.
A DOCX file is a ZIP package containing XML. For indexing or previews, read word/document.xml and combine its text nodes. This does not preserve layout.
Read document.xml
<?php
$zip = new ZipArchive();
if ($zip->open(__DIR__ . '/document.docx') !== true) throw new RuntimeException('Cannot open DOCX.');
$xml = $zip->getFromName('word/document.xml'); $zip->close();
if ($xml === false) throw new RuntimeException('Missing document XML.');
$dom = new DOMDocument(); $dom->loadXML($xml, LIBXML_NONET);
$xpath = new DOMXPath($dom);
$xpath->registerNamespace('w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main');
foreach ($xpath->query('//w:p') as $paragraph) {
$parts = [];
foreach ($xpath->query('.//w:t', $paragraph) as $text) $parts[] = $text->textContent;
if ($parts) echo implode('', $parts) . "\n";
}Know the limits
- Treat the result as plain text, not preserved layout.
- Account for headers and footers when required.
- Use a document library for styles and tracked changes.
- Keep network access disabled while parsing untrusted XML.
Know which document parts you need
The main document XML covers ordinary body paragraphs, but headers, footers, comments, footnotes, and text boxes live in other package parts. Define whether the result is for search indexing, preview, or conversion.
Test paragraphs with tabs, line breaks, tables, and non-English text. Treat the output as plain text and compare it with the source document before relying on it for legal or archival use.
- Parse XML with network access disabled.
- Limit archive size before opening.
- Use a document library for layout preservation.
Keep resource limits explicit and make failure cleanup part of the example. Log enough context to diagnose the operation without recording passwords, private message bodies, or uploaded file contents.
Continue with ZIP archives and temporary files.
Reference: PHP DOMDocument reference.