<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Blog</title>
  <subtitle>Product updates and a look inside YiiPress.</subtitle>
  <link href="https://yiipress.yiiframework.com/blog/"/>
  <link href="https://yiipress.yiiframework.com/blog/feed.xml" rel="self" type="application/atom+xml"/>
  <id>https://yiipress.yiiframework.com/blog/</id>
  <updated>2026-11-02T00:00:00+00:00</updated>
  <generator uri="https://github.com/yiisoft/yiipress">YiiPress</generator>
  <entry>
    <title>How it works</title>
    <link href="https://yiipress.yiiframework.com/blog/how-it-works/"/>
    <id>https://yiipress.yiiframework.com/blog/how-it-works/</id>
    <published>2026-11-02T00:00:00+00:00</published>
    <updated>2026-11-02T00:00:00+00:00</updated>
    <summary>How YiiPress packs PHP and native extensions into one executable, builds pages, and runs rendering workers.</summary>
    <content type="html">&lt;p&gt;YiiPress is written in PHP, but you can use it without installing PHP or Composer.&lt;br /&gt;
You download one executable file. It contains PHP, the YiiPress code, and the extensions needed to build your site.&lt;br /&gt;
The build produces static files that you can publish to a web host.&lt;/p&gt;
&lt;h2&gt;PHP and the application in one file&lt;/h2&gt;
&lt;p&gt;YiiPress still runs on the Zend Engine, the engine that executes PHP code.&lt;br /&gt;
The packaging process does not convert PHP classes into machine code. It puts a PHP runtime and the application in one&lt;br /&gt;
file. The runtime is the part that executes the PHP code.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://static-php.dev/&quot;&gt;static-php-cli&lt;/a&gt; builds PHP with the selected extensions.&lt;br /&gt;
Its &lt;a href=&quot;https://micro.static-php.dev/en/index.html&quot;&gt;micro SAPI&lt;/a&gt; runs PHP from a single executable.&lt;br /&gt;
It provides a file called &lt;code&gt;micro.sfx&lt;/code&gt;, which can be combined with PHP code or a PHAR archive.&lt;br /&gt;
A PHAR is an archive that holds a PHP application and its dependencies. It also contains a startup script called a stub.&lt;/p&gt;
&lt;p&gt;The Linux build combines these parts:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;flowchart TD
    app[&amp;quot;YiiPress code, config, theme and runtime dependencies&amp;quot;] --&amp;gt; phar[&amp;quot;yiipress.phar&amp;quot;]
    php[&amp;quot;PHP sources and selected native extensions&amp;quot;] --&amp;gt; spc[&amp;quot;static-php-cli&amp;quot;]
    spc --&amp;gt; micro[&amp;quot;micro.sfx&amp;quot;]
    phar --&amp;gt; combine[&amp;quot;spc micro:combine&amp;quot;]
    micro --&amp;gt; combine
    combine --&amp;gt; executable[&amp;quot;yiipress executable&amp;quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you run the executable, PHP runs the PHAR stub. The stub makes the archive's files available and loads the &lt;code&gt;yii&lt;/code&gt;&lt;br /&gt;
script inside it. That script starts the console application. You can then use commands such as &lt;code&gt;yiipress build&lt;/code&gt; and&lt;br /&gt;
&lt;code&gt;yiipress serve&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The macOS and Windows builds also combine micro and PHAR, but use separate build scripts.&lt;br /&gt;
Each executable runs on its target operating system and CPU architecture. A Linux executable cannot run on every platform.&lt;/p&gt;
&lt;h2&gt;Keep the download small&lt;/h2&gt;
&lt;p&gt;YiiPress includes the files and extensions it needs to run. Development tools stay out of the package.&lt;/p&gt;
&lt;p&gt;The PHAR contains &lt;code&gt;config/&lt;/code&gt;, &lt;code&gt;src/&lt;/code&gt;, &lt;code&gt;themes/&lt;/code&gt;, Composer runtime dependencies, and the &lt;code&gt;yii&lt;/code&gt; script.&lt;br /&gt;
The archive filter removes files such as dependency tests, examples, documentation, and development-tool settings.&lt;br /&gt;
The build also strips comments, but keeps metadata that running code reads through reflection, PHP's way to inspect&lt;br /&gt;
classes at runtime.&lt;br /&gt;
Files inside the PHAR use gzip compression.&lt;/p&gt;
&lt;p&gt;The PHP build includes selected extensions for tasks such as Markdown conversion, code highlighting, YAML parsing, and&lt;br /&gt;
XML output. It does not include every PHP extension. On Linux, the build uses musl to link libraries into the executable&lt;br /&gt;
and UPX to compress it. Other platforms use different packaging steps.&lt;br /&gt;
The PHAR, the executable, and the compressed download are different files, so their sizes differ too.&lt;/p&gt;
&lt;p&gt;The application also avoids parts it does not need. It uses plain PHP templates without a view or widget stack.&lt;br /&gt;
Its preview server uses ReactPHP streams. It does not need FPM or Apache to run &lt;code&gt;yiipress serve&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;PHP connects the parts; native code processes the text&lt;/h2&gt;
&lt;p&gt;Yii3 supplies dependency injection, console integration, routing, and middleware for the preview application.&lt;br /&gt;
YiiPress uses these services to connect its content models, index, processors, templates, and file writers.&lt;/p&gt;
&lt;p&gt;Two text-processing tasks use native extensions, which run compiled code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ext-mdparser&lt;/code&gt;, from &lt;code&gt;iliaal/mdparser&lt;/code&gt;, converts Markdown to HTML with MD4C, a parser written in C.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ext-highlighter&lt;/code&gt;, from &lt;code&gt;yiipress/highlighter&lt;/code&gt;, highlights code with syntect, written in Rust.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The build includes these extensions in the PHP runtime. Users do not need to install separate Markdown or highlighting&lt;br /&gt;
libraries. PHP calls the extensions and controls the rest of the build.&lt;/p&gt;
&lt;p&gt;The site build has four main steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Parse.&lt;/strong&gt; Read YAML configuration and entry front matter, the settings at the start of each Markdown file.&lt;br /&gt;
The parser also reads each body to find inline tags. Each entry stores the body's position in the source file instead&lt;br /&gt;
of keeping the full body in memory. Rendering can read it again when needed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Index.&lt;/strong&gt; Resolve page URLs, filter drafts and future entries, sort collections, and connect authors and taxonomies.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Render.&lt;/strong&gt; Read entry bodies, run content processors, convert Markdown to HTML, and render PHP templates.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Write.&lt;/strong&gt; Save pages, listings, feeds, the sitemap, search data, and assets.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Incremental builds reuse earlier results when the relevant inputs have not changed.&lt;br /&gt;
YiiPress uses source hashes, rendering settings, and output dependencies to decide what to rebuild.&lt;br /&gt;
Native extensions make text processing faster; the cache avoids repeating work.&lt;/p&gt;
&lt;h2&gt;Give each rendering worker its own archive&lt;/h2&gt;
&lt;p&gt;YiiPress can render pages in parallel. Each worker is a separate process that handles rendering jobs.&lt;/p&gt;
&lt;p&gt;Starting workers with a process fork caused a problem with PHAR files. A child process inherits the parent's open file&lt;br /&gt;
handles. If both processes read the same PHAR handle, they share its read position. Concurrent class loading can then&lt;br /&gt;
read the wrong bytes and report an archive error, such as a CRC32 checksum mismatch.&lt;/p&gt;
&lt;p&gt;The rendering pool uses &lt;code&gt;proc_open()&lt;/code&gt; to start independent processes instead. Each worker opens its own package,&lt;br /&gt;
sets up the parts needed for rendering, receives a job, and writes separate output files.&lt;br /&gt;
The workers do not share a PHAR read position. This approach also works on Windows.&lt;/p&gt;
&lt;p&gt;Starting and setting up processes takes time. YiiPress therefore renders small batches sequentially when they fall below&lt;br /&gt;
its worker thresholds.&lt;/p&gt;
&lt;h2&gt;Keep package files separate from project files&lt;/h2&gt;
&lt;p&gt;The embedded archive contains the engine. The user's website lives outside it.&lt;br /&gt;
YiiPress uses package paths to read its own files. It uses the project directory, where the command runs, to find site&lt;br /&gt;
content, local themes, and output paths.&lt;/p&gt;
&lt;p&gt;A package may be installed in a directory where the user cannot write files.&lt;br /&gt;
For PHAR and binary installations, YiiPress therefore stores its runtime cache and incremental build records in the&lt;br /&gt;
operating system's temporary directory. The cache location depends on the project path, so separate projects have&lt;br /&gt;
separate caches. &lt;code&gt;yiipress clean&lt;/code&gt; removes the project's build cache and the configured output directory.&lt;/p&gt;
&lt;h2&gt;Publish the generated files&lt;/h2&gt;
&lt;p&gt;The executable builds the site and runs a local preview. &lt;code&gt;yiipress serve&lt;/code&gt; serves the generated files and reloads the&lt;br /&gt;
browser when they change. The published website does not need a PHP application server.&lt;/p&gt;
&lt;p&gt;Run &lt;code&gt;yiipress build&lt;/code&gt;, then publish the contents of &lt;code&gt;output/&lt;/code&gt; to a static host.&lt;br /&gt;
Those pages, feeds, styles, scripts, and assets are the website. Build again after changing content or templates.&lt;br /&gt;
Set &lt;code&gt;base_url&lt;/code&gt; to the public site URL so canonical links and feeds use the correct address.&lt;/p&gt;
&lt;p&gt;YiiPress also provides a Linux distroless container image for building sites.&lt;br /&gt;
This is a small image containing the packaged executable, without a separate PHP or Composer installation.&lt;br /&gt;
Engine development uses a separate Docker environment with debugging and build tools.&lt;/p&gt;
&lt;p&gt;This packaging approach lets users run a PHP application as a single command-line tool.&lt;br /&gt;
The application keeps its PHP libraries and templates. Other PHP tools can use the same approach if their extensions,&lt;br /&gt;
file access, and worker processes work inside such a package.&lt;/p&gt;
&lt;p&gt;For more detail, see &lt;a href=&quot;../engine.md&quot;&gt;Engine&lt;/a&gt; and &lt;a href=&quot;../binaries-phar-docker.md&quot;&gt;Binaries, PHAR, Docker&lt;/a&gt;.&lt;br /&gt;
To build your own site, start with the &lt;a href=&quot;../quickstart.md&quot;&gt;Quickstart&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
</feed>
