Opening Encrypted PDFs
Every method that reads an existing PDF takes an optional password. Supply it and the document opens normally; everything downstream behaves as it would for an unencrypted file.
Opening With a Password#
importFromFile() and importRawData() take the password after $pages:
use Pop\Pdf\Pdf;
$document = Pdf::importFromFile(__DIR__ . '/protected.pdf', password: 'open-me');
$document->getNumberOfPages(); // 1
Either password opens the document — the user password and the owner password are interchangeable for getting in, and differ only in the permissions that apply afterward.
Opening is transparent, and that is the part worth remembering: the Document you get back does not
know it came from an encrypted file. hasSecurity() is false, and writing it out again produces an
unencrypted PDF unless you call setSecurity() yourself:
use Pop\Pdf\Pdf;
$document = Pdf::importFromFile(__DIR__ . '/protected.pdf', password: 'open-me');
$document->hasSecurity(); // false — encryption is not carried over
Reading and Classifying#
The extraction and classification entry points take the password after $pages and $pageLimit:
use Pop\Pdf\Pdf;
$text = Pdf::extractTextFromFile(__DIR__ . '/protected.pdf', password: 'open-me');
extractTextFromData(), isImageOnlyDocument(), isImageOnlyData(), getImageOnlyPages() and
getImageOnlyPagesFromData() all take it in the same position. extractAsImages() is the exception —
it has no password argument, because it rasterizes through the imagick extension rather than through
the reader the other methods share, so an encrypted source cannot be rasterized this way.
Merging Encrypted Sources#
merge() and mergeRawData() take an array of passwords instead of one, keyed the same way as the
sources, so a batch can mix protected and unprotected files:
use Pop\Pdf\Document;
use Pop\Pdf\Pdf;
$merged = Pdf::merge(
[__DIR__ . '/report.pdf', __DIR__ . '/protected.pdf'],
new Document(),
[1 => 'open-me']
);
A source with no entry, or a null entry, is opened with no password — only the encrypted ones need
naming. As with a single import, the merged result carries no encryption of its own.
When the Password Is Missing or Wrong#
Both cases raise Pop\Pdf\Extract\Exception, with messages that tell them apart:
use Pop\Pdf\Pdf;
use Pop\Pdf\Extract\Exception;
try {
Pdf::extractTextFromFile(__DIR__ . '/protected.pdf');
} catch (Exception $exception) {
echo $exception->getMessage();
// Error: This PDF is encrypted; a password is required to open it.
}
Supplying the wrong one reports Error: The password provided is incorrect for this encrypted PDF.
instead, so a caller can tell "this file needs a password" from "that password was not it".
What Cannot Be Opened#
AES-128 and AES-256 are the supported algorithms. A document encrypted any other way raises an exception naming the problem rather than failing obscurely:
- RC4, the older algorithm, is not supported
- Revision 5, a deprecated Adobe extension, is refused the same way
- a document whose cross-reference data is too damaged to locate its encryption dictionary is refused rather than reported as an empty unencrypted document
Two quirks are worth knowing if you meet them. A source PDF's own literal strings are not decrypted on
the way in, so values read out of an encrypted source come back as raw bytes rather than text — which
is why importing an encrypted document deliberately skips its metadata rather than importing
gibberish. And a document combining /EncryptMetadata false with an XMP metadata stream fails to open.
See Also#
- Encryption & Permissions — setting a password on a document you are writing
- Importing — the rest of the import API these passwords slot into
- Merging — the source ordering and starter document the password array joins
- Extracting Text — what the password gets you access to