Template inheritance in vanilla PHP in 35 lines of code?

Somehow I came across a project on WordPress (WP), where I needed to make a custom theme. In WP, templates are native, which is good - you don't need to learn an additional language. But I really wanted to inherit templates like in Twig , and PHP can't do that out of the box.





It remains to solve the inheritance issue. After studying the problem, it was decided to be inspired by the phpti library , in which there were a couple of points that I really wanted to fix:





  • The author of the library wrote β€œEvery Block is Always Executed!” In capital letters, that is, all blocks are executed, even if they are overridden, and will never be output.





  • - , , , - .





  • - . ob_start



    .





phpti startblock/endblock



import



:





<!--  -->
<?php startblock('blockName') ?>
    <!--     -->
<?php endblock() ?>
<!--  -->
      
      



index.php







<?php include 'layout.php' ?> <!--    -->

<?php startblock('blockName') ?>
    <!--   -->
<?php endblock() ?>
      
      



:





  • start/end . , .





  • . , , . . ?





  • , : , , .





, :





layout.php







// 
<!--  -->
<?php slot('blockName', function(){ ?>
    <!--     -->
<?php }) ?>
<!--  -->
      
      



index.php







<?php block('blockName', function(){ ?>
    <!--   -->
<?php }) ?>

<?php include 'layout.php' ?> <!--    -->
      
      



slot



block



, , , .





. , .





root.php



- , :





<!DOCTYPE html>
<html>
  <head>
    <title>
        <!-- '' -       -->
        <?php slot('title') ?>
    </title>
  </head>
  <body>
    <div id="root">
      <!--   ,      -->
      <?php slot('body', function () { ?>
        <p>'body' :: root.php</p>
      <?php }) ?>
    </div>
  </body>
</html>
      
      



two-columns.php



- :





<?php 
block('title', function () { ?> <!-- '' -      -->
  Title :: two-columns.php
<?php });

block('body', function () { ?>
  <div id="two-columnts">
    <div id="main">
      <?php slot('main', function () { ?> <!--    -->
        <p>'main' :: two-columns.php</p>
      <?php }) ?>
    </div>
    <div id="side">
      <?php slot('side', function () { ?>
        <p>'side' :: two-columns.php</p>
      <?php }) ?>
    </div>
  </div>
  <div id="footer">
    <?php slot('footer', function () { ?>
      <p>'footer' :: two-columns.php</p>
    <?php }) ?>
  </div>
<?php });
include './root.php'; //   root.php
      
      



index.php



- , :





<?php
require_once '../src/InheritTpl.php'; 

block('title', function () { ?> 'title' :: index.php <?php });

block('side', function () { ?>
  <p>'side' :: index.php</p>
<?php });

block('main', function () { ?>
  <div id="main-index"> <!--     -->
    <?php super() ?> <!--       -->
  </div>
<?php });

//     ,    ?
block('main', function () { ?>
  <div id="main-index"> <!--      -->
    <?php super() ?>
  </div>
<?php });

//  'footer'    

include './two-columns.php';
      
      



( ):





<!DOCTYPE html>
<html>
  <head>
    <title> 'title' :: index.php </title>
  </head>
  <body>
    <div id="root">
      <div id="two-columnts">
        <div id="main">
          <div id="main-index"> <!--     -->
            <div id="main-index"> <!--      -->
              <p>'main' :: two-columns.php</p>
            </div>
          </div>
        </div>
        <div id="side">
          <p>'side' :: index.php</p>
        </div>
      </div>
      <div id="footer">
        <p>'footer' :: two-columns.php</p>
      </div>
    </div>
  </body>
</html>
      
      



. , ?





Let's rewrite the example above for the phpti library. Let's give her a little head start, because there are no heavyweight overridden blocks in the example.





We will compare the time of 10,000 renders on PHP 8.0.2 and a 3.6GHz processor.





  • phpti: 0.831 seconds





  • subject: 0.353 seconds





As a conclusion, we can say that the size of the library has been reduced by 10 times, while the speed of the inheritance mechanism has increased at least 2 times.





You can view the source code here .








All Articles