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