Используем PHP по назначению


    upd: Осторожно, текст содержит сатиру и кодобред

    Язык программирования PHP берёт своё начало в 1995 году и является продуктом эпохи зарождения современных веб стандартов, таких как http (версия 1.0 — 1996), html (версия 2.0 — 1995), javascript (1995 год), url (1990 — 1994 года). Первоначально аббревиатура php имела расшифровку Personal Home Page Tools, далее трансформировавшись в Hypertext Preprocessor или «препроцессор гипертекста». Об использовании PHP в качестве препроцессора и будет посвящено несколько следующих абзацев.

    Интерпретатор PHP позволяет вставлять в любой текст специальные тег <?php ?>, с помощью которого можно подставить в страницу динамический контент, что очень удобно использовать внутри html документов. Полученный результат сразу подаётся на стандартное устройство вывода, известное как stdout (подробнее смотри здесь). Есть возможность буферизовать вывод до востребованности через функцию ob_start, но для нашей первой html страницы это не понадобится. Самый последний стандарт html под номером 5 ввёл несколько новых тегов для упрощения разметки, повышения читаемости и семантичности веба (что бы это не значило). Поэтому сразу воспользуемся всей мощью HTML5 и напишем шаблон страницы со вставками на рассматриваемом препроцессоре.


    Сохраним эту страницу в файл index.html. Функционал блога в первой его версии будет предусматривать хранение публикаций в виде html страниц внутри заранее заданной директории (например pages/) и меню позволяющее перейти сразу на нужную публикацию.

    Пример публикации, которая будет выведена в ленту блога.


    В корне проекта добавим директорию pages/ и сохраним нашу статью под произвольным именем, например как 2018-trends.html.

    Теперь нам нужен веб сервер для обработки входящих http запросов от пользователей, и сервер приложения для бизнес логики. Чтобы не плодить лишнии сущности напишем небольшую программу на языке программирования Go, которая будет выступать и в роли веб сервера, и содержать код блога. Для передачи пользовательских запросов из хостовой программы в препроцессор воспользуемся стандартным потоком ввода (stdin), для сериализации данных воспользуемся популярным форматом для сериализации данных — json.

    Скрипт для обработки входных данных:

    <?php
    $input = trim(fgets(STDIN));
    $input = json_decode($input, true);
    include("index.html");

    Код блога:

    main.go
    package main
    
    import (
    	"encoding/json"
    	"io/ioutil"
    	"net/http"
    	"os/exec"
    	"strings"
    
    	"github.com/labstack/echo"
    )
    
    func main() {
    	e := echo.New()
    	e.GET("/", index)
    	e.GET("/pages/:page", index)
    	e.Start(":8000")
    }
    
    func index(c echo.Context) error {
    	outData := struct {
    		Menu  []string `json:"menu"`
    		Pages []string `json:"pages"`
    	}{}
    	outData.Menu = make([]string, 0)
    	outData.Pages = make([]string, 0)
    
    	page := c.Param("page")
    
    	files, _ := ioutil.ReadDir("pages")
    	for _, file := range files {
    		if !file.IsDir() {
    			outData.Menu = append(outData.Menu, file.Name())
    		}
    		if page != "" && page == file.Name() {
    			fbody, _ := ioutil.ReadFile("pages" + "/" + file.Name())
    			outData.Pages = append(outData.Pages, string(fbody))
    		} else if page == "" {
    			fbody, _ := ioutil.ReadFile("pages" + "/" + file.Name())
    			outData.Pages = append(outData.Pages, string(fbody))
    		}
    
    	}
    
    	rendered := renderContent(outData)
    
    	return c.HTMLBlob(http.StatusOK, rendered)
    }
    
    func renderContent(input interface{}) []byte {
    	jsonInput, _ := json.Marshal(input)
    
    	tmplEngine := exec.Command("php", "-f", "index.php")
    	tmplEngine.Stdin = strings.NewReader(string(jsonInput))
    	rendered, _ := tmplEngine.Output()
    
    	return rendered
    }


    Теперь запускаем на исполнение программу через go run и делаем запрос на страницу через любой браузер, например таким образом:

    links2 http://localhost:8000

    Результат представлен на КДПВ.

    Пытливый читатель может заметить, что мы сильно теряем в производительности запуская на каждый запрос php процесс. Данный момент легко оптимизировать используя механизм pipes и запуская php процесс единожды в фоне, но это уже совсем другая история.
    Поделиться публикацией

    Похожие публикации

    Комментарии 17
      +5
      А в чём мораль-то?
      Если у нас сервер на Go (под лозунгом «не плодить лишних сущностей»), то на кой чёрт нам сдался PHP? Да и вообще тут хватит одного HTML.
      Или я не понял какую-то тонкую шутку?
        –1
        Это была попытка освоить жанр сатиры.
        И небольшая демонстрация механизма pipes, ipc, и замена достаточно неудобного go шаблонизатора на более удобный
          +5
          Уровень сатиры поймал integer overflow
          +4
          типа пхп это шаблонизатор
            +5

            Ну во-первых, это красиво :)
            И не надо гошный template использовать, зато можно использовать PHP как движок шаблонов.

            0
            <?php print($page) ?>

            <?= $page ?> — надо по максимуму как шаблонизатор использовать
              0
              Полностью согласен, но сожалению на моей системе при установке не были включены short tags, и мне не захотелось перегружать статью подробностями.
                +4

                <?= — это не short-tag, а алиас на <?php echo, <? — вот short-tag
                http://php.net/manual/ru/language.basic-syntax.phptags.php


                Тег <?= доступен всегда, вне зависимости от настройки short_open_tag.
                  +3
                  С версии 5.4 тег <?= доступен всегда, вне зависимости от настройки short_open_tag
                  ссылка на документацию
                    0
                    Спасибо! Значит меня сбила с толку ошибка в другом месте когда набирал пример.
                0
                Я не знаком с Го, но там что, нет шаблонизатора?
                  0
                  Шаблонизатор есть, но его удобство оставляет желать лучшего. И внимание, спойлер. Статья в хабе «Кодобред». Именно так как я написал в статье, делать не надо ни в коем случае.
                    +3
                    На мой взгляд, стоит поставить что-то вроде яркой шапки в духе «Осторожно, сатира» (или кодобред). Потому что я начал читать на полном серьезе, а теги как-то не особо замечаются (у меня все хабы агрегируются). Плюс начало очень такое формальное, с исторической справкой, совсем непонятно, что будет сатира. Да и сейчас на хабре в меру часто появляются не очень качественные статьи от сильно начинающих, и у меня возникло ощущение, что это одна из них.
                      0

                      На самом деле он крут в своей простоте, но к нему надо привыкнуть.
                      И есть опенсорсные движки, приближенные к тому, к чему мы все привыкли

                        0
                        Есть стероиды в виде Masterminds/sprig. С ними Go'шный шаблонизатор более чем юзабелен. Подобная связка без проблем используется в Kubernetes Helm и в Hugo, и, по мощности, в принципе, не уступает тому же PHP как шаблонизатору. Последний, кстати, как шаблонизатор тоже так себе. Лучше уж что-то вменяемое типа jinja2/twig/liquid с наследованием шаблонов и прочими вкусняшками)
                      0
                      Меня одного смутил footer после закрытого body?
                        0
                        Исправлено!

                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                      Самое читаемое