Creating Documents
A Document is the root object that all the other pieces of Pop PDF assembles into — pages, fonts, styles and
forms.
Creating a Document#
The constructor takes an optional first page, optional metadata and an optional style or array of styles, and every argument can be left off:
use Pop\Pdf\Document;
use Pop\Pdf\Document\Page;
$document = new Document();
$document = new Document(new Page(Page::LETTER));
An empty new Document() holds no pages at all — Adding Pages covers every way to
give it one. Leaving the metadata argument off still creates a default Metadata instance, so
getMetadata() always returns an object rather than null. See
Metadata for the second argument and Adding Text
for the third.
Adding Pages#
addPage() takes a Page object and appends it, returning the document so calls chain:
use Pop\Pdf\Document;
use Pop\Pdf\Document\Page;
$document = new Document();
$document->addPage(new Page(Page::LETTER));
$document->addPage(new Page(Page::A4));
Sizes can differ per page — see Pages & Coordinates.
addPages() takes an array of Page objects and adds every one of them in order, in a single call:
use Pop\Pdf\Document;
use Pop\Pdf\Document\Page;
$document = new Document();
$document->addPages([
new Page(Page::LETTER),
new Page(Page::LETTER),
new Page(Page::LEGAL),
]);
createPage() builds the Page for you — pass it the same size argument a Page constructor takes
— adds it to the document, and returns the new page rather than the document, so it's the shortcut
when the next thing you do is add content to that page:
use Pop\Pdf\Document;
use Pop\Pdf\Document\Page;
$document = new Document();
$page = $document->createPage(Page::LETTER);
All three count toward getNumberOfPages() the same way, and pages keep the
order they were added in until orderPages() changes it.
createPage() is the odd one out among the three, returning the page itself rather than the
document, since it hands back the object you're about to draw on:
use Pop\Pdf\Document;
use Pop\Pdf\Document\Page;
use Pop\Pdf\Document\Page\Text;
use Pop\Pdf\Document\Font;
$document = new Document();
$document->addFont(Font::ARIAL);
$page = $document->createPage(Page::LETTER);
$page->addText(new Text('Invoice #1042', size: 14), 'Arial', x: 100, y: 700);
Copying, Reordering and Deleting#
copyPage() clones an existing page, by its 1-indexed position, and appends the clone at the end of
the document. The clone is independent from the moment it's made — changes to the copy never touch
the original:
use Pop\Pdf\Document;
use Pop\Pdf\Document\Page;
$document = new Document();
$document->addPages([new Page(Page::LETTER), new Page(Page::LEGAL)]);
$copy = $document->copyPage(1);
echo $document->getNumberOfPages(); // 3
The clone carries every image, text run, path and field the original has. Pass false as the second
argument for an identical size and index with none of it:
$blank = $document->copyPage(2, preserveContent: false);
A position outside the document raises Pop\Pdf\Document\Exception, naming the position:
try {
$document->copyPage(99);
} catch (\Pop\Pdf\Document\Exception $exception) {
echo $exception->getMessage(); // Error: That page (99) does not exist.
}
orderPages() takes an array naming, in the new order, the 1-indexed page number for each position
— [3, 1, 2] puts the current page 3 first, page 1 second, page 2 last. The array must name every
page exactly once; a wrong length or an unknown page number raises Pop\Pdf\Document\Exception:
use Pop\Pdf\Document;
use Pop\Pdf\Document\Page;
$document = new Document();
$document->addPages([new Page(Page::LETTER), new Page(Page::LEGAL), new Page(Page::A4)]);
$document->orderPages([3, 1, 2]);
The two error cases have distinct messages:
try {
$document->orderPages([3, 1]); // only 2 entries for a 3-page document
} catch (\Pop\Pdf\Document\Exception $exception) {
echo $exception->getMessage();
// Error: The pages array passed does not contain the same number of pages as the PDF.
}
try {
$document->orderPages([3, 1, 9]);
} catch (\Pop\Pdf\Document\Exception $exception) {
echo $exception->getMessage();
// Error: The pages array passed contains a page that does not exist.
}
deletePage() removes a page by its 1-indexed position without renumbering the rest: delete page 1
from a three-page document and pages 2 and 3 keep their numbers, while getPage(1) raises
Pop\Pdf\Exception until something fills it. A page added afterward takes the next number after the
highest in use, not the gap — delete page 1, add one, and you get pages 2, 3 and 4:
use Pop\Pdf\Document;
use Pop\Pdf\Document\Page;
$document = new Document();
$document->addPages([new Page(Page::LETTER), new Page(Page::LEGAL), new Page(Page::A4)]);
$document->deletePage(1);
echo $document->getNumberOfPages(); // 2
orderPages() closes that gap, since it rebuilds the page list from scratch — passing the surviving
page numbers in their current order renumbers the document back to a clean, gap-free sequence:
$document->orderPages([2, 3]);
echo $document->getPage(1)->getWidth(); // the page that used to answer to number 2
deletePage() raises the same exception, worded the same way, for a position the document does not
have.
The Current Page#
An empty new Document() starts with no current page at all — getCurrentPage() returns null and
getNumberOfPages() returns 0 until the first page is added. From there it moves automatically:
addPage(), addPages(), createPage() and copyPage() all set it to the page most recently
added. setCurrentPage() moves it explicitly and getCurrentPage() reads it back:
use Pop\Pdf\Document;
use Pop\Pdf\Document\Page;
$document = new Document();
$document->addPages([new Page(Page::LETTER), new Page(Page::LETTER)]);
$document->setCurrentPage(1);
echo $document->getCurrentPage(); // 1
echo $document->getNumberOfPages(); // 2
setCurrentPage() raises Pop\Pdf\Document\Exception for a page number the document doesn't have.
Deleting the current page moves the pointer instead of leaving it dangling: it becomes one less than
the pages remaining, or nothing once the document is empty — delete page 5 from a five-page document
and the current page becomes 3.
The current page is bookkeeping for the caller only — nothing inside Pop PDF reads it back to decide what to compile.
Inspecting a Document#
Every collection a document holds — pages, fonts, styles and forms — has a has*() that reports
whether any exist and a get*() that returns them.
use Pop\Pdf\Document;
use Pop\Pdf\Document\Page;
use Pop\Pdf\Document\Font;
$document = new Document(new Page(Page::LETTER));
$document->addFont(Font::ARIAL);
$document->hasPages(); // true
$document->hasFonts(); // true
$document->hasStyles(); // false
$document->hasForms(); // false
$document->getPages(); // array of Page objects
$document->getAvailableFonts(); // ['Arial']
getPage() returns a single page by its 1-indexed position, and getFont() and getStyle() return
a single member of their collection by name — all three raise an exception when the document doesn't
have what was asked for. isFontAvailable()/hasFont() and isStyleAvailable()/hasStyle() are
each the same check under two names:
$page = $document->getPage(1);
$arial = $document->getFont('Arial');
$document->isFontAvailable('Arial'); // true
getForm() is the one accessor here that doesn't throw — a name the document doesn't have returns
null, so it's safe to call before checking hasForms():
use Pop\Pdf\Document;
$document = new Document();
$form = $document->getForm('contact'); // null, no exception
The full set of collection accessors:
getPages()/getPage($p)/hasPages()— every page, one page by position, or whether any existgetFonts()/getFont($name)/hasFonts()/getAvailableFonts()/hasFont($name)— the document's fonts, keyed by namegetStyles()/getStyle($name)/hasStyles()/getAvailableStyles()/hasStyle($name)— the same shape for stylesgetForms()/getForm($name)/hasForms()— form definitions, added withaddForm()
Compression#
setCompression() turns on stream compression for everything the document writes; isCompressed()
reports whether it is on. It defaults to false:
use Pop\Pdf\Document;
$document = new Document();
$document->isCompressed(); // false
$document->setCompression(true);
$document->isCompressed(); // true
The saving is real and depends on content — a five-page document built from forty lines of repeated
text per page plus one filled rectangle compiled to 29,562 bytes uncompressed and 4,506 bytes with
setCompression(true), a difference of 25,056 bytes, about 85% smaller.
Turn it on before the first call that compiles the document — writeToFile(), outputToHttp() or a
cast to string — since compression happens at compile time, not when content is added.
PDF Version#
setVersion() and getVersion() control the version number written into the file header. It
defaults to 1.7:
use Pop\Pdf\Document;
$document = new Document();
$document->getVersion(); // 1.7
$document->setVersion(1.4);
$document->getVersion(); // 1.4
The version compiles straight into the first line of the output — a document with setVersion(1.4)
in force opens with %PDF-1.4 rather than %PDF-1.7. Pop PDF doesn't gate any feature behind the
version number, so setting it lower disables nothing; it's only worth changing to match a target
format requirement a downstream consumer specifies.
Rendering to a String#
Casting a document to a string compiles it and returns the raw PDF bytes in memory, the same bytes
writeToFile() writes for that document — see
Getting the Raw Bytes.
A short document assembled from several pieces on this page — two pages built directly, one copied and reordered ahead of them:
use Pop\Pdf\Document;
use Pop\Pdf\Document\Page;
use Pop\Pdf\Document\Page\Text;
use Pop\Pdf\Document\Font;
$document = new Document();
$document->addFont(Font::ARIAL);
$document->addPage(new Page(Page::LETTER));
$page = $document->createPage(Page::LETTER);
$page->addText(new Text('Page two', size: 12), 'Arial', x: 100, y: 700);
$document->copyPage(1, preserveContent: false);
$document->orderPages([3, 1, 2]);
echo $document->getNumberOfPages(); // 3
echo strlen((string)$document); // the compiled byte count
See Also#
- Pages & Coordinates — sizing and positioning the pages a document holds
- Metadata — the document's title, author and the rest of the info object
- Saving & Output — writing a document to a file or sending it to a browser