Pre-loader

/ K2 Cloud ERP for PHP / Різні задачі по PHP / Examples та навчання / Як ми створили додаток із живими прикладами PHP-коду – бери та використовуй!

Як ми створили додаток із живими прикладами PHP-коду – бери та використовуй!

Створення додатку для демонстрації PHP-коду: досвід та приклад реалізації

У сучасному світі розробники часто стикаються із завданням швидкого створення функціональних додатків. Саме тому було створено додаток для демонстрації коду, який не тільки відображає приклади програмування, а й дозволяє їх виконувати. Це дає змогу користувачам одразу тестувати запропоновані рішення та вчитися на практичних прикладах.

Ідея створення

Для того, щоб продемонструвати гнучкість і швидкість розробки в системі K2 Cloud ERP, ми розробили спеціальний додаток, який дозволяє завантажувати та виконувати PHP-код безпосередньо у веб-інтерфейсі. Ця функціональність корисна як для початківців, так і для досвідчених програмістів, які хочуть швидко тестувати свої рішення.

Функціональність додатку

✅ Виконання PHP-коду в браузері без потреби у локальному сервері. ✅ Текстовий редактор з підсвіткою синтаксису для зручного написання коду. ✅ Перемикання тем оформлення редактора для комфорту роботи. ✅ Навігація по сторінках для кращої організації матеріалу.

Код рішення


class CodeEditor {
    private $files = [];
    private $descriptions = [];
    private $themes = [
        ’default’ => ’https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css’,
        ’dark’ => ’https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/monokai.min.css’,
        ’light’ => ’https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/github.min.css’
    ];
    private $currentTheme = ’dark’;

    public function addExample($filename, $description) {
        if (file_exists($filename)) {
            $this->files[] = $filename;
            $this->descriptions[$filename] = $description;
        } else {
            throw new Exception("File not found: $filename");
        }
    }

    public function setTheme($theme) {
        if (array_key_exists($theme, $this->themes)) {
            $this->currentTheme = $theme;
        }
    }

    private function getLanguage($filename) {
        $ext = pathinfo($filename, PATHINFO_EXTENSION);
        $langMap = [
            ’php’ => ’php’,
            ’js’ => ’javascript’,
            ’py’ => ’python’,
            ’html’ => ’html’,
            ’css’ => ’css’
        ];
        return $langMap[$ext] ?? ’plaintext’;
    }

    public function render() {
        echo ’<!DOCTYPE html><html lang="en"><head>’;
        echo ’<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">’;
        echo ’<title>Code Editor</title>’;
        echo ’<link rel="stylesheet" href="’ . $this->themes[$this->currentTheme] . ’">’;
        echo ’<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>’;
        echo ’<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/plugins/line-numbers/highlightjs-line-numbers.min.js"></script>’;
        echo ’<script>hljs.highlightAll(); document.addEventListener("DOMContentLoaded", function() {hljs.initLineNumbersOnLoad();});</script>’;
        echo ’<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">’;
        echo ’<style>pre code.hljs { padding-left: 2em; }</style>’;
        echo ’</head><body class="container mt-3">’;
        
        echo ’<label for="themeSelector">Choose Theme: </label>’;
        echo ’<select id="themeSelector" class="form-select w-25 mb-3">’;
        foreach ($this->themes as $theme => $url) {
            echo ’<option value="’ . $theme . ’"’ . ($theme === $this->currentTheme ? ’ selected’ : ’’) . ’>’ . ucfirst($theme) . ’</option>’;
        }
        echo ’</select>’;
        
        echo ’<ul class="nav nav-tabs" id="codeTabs" role="tablist">’;
        foreach ($this->files as $index => $file) {
            echo ’<li class="nav-item" role="presentation">’;
            echo ’<button class="nav-link ’.($index === 0 ? ’active’ : ’’).’" id="tab-’.basename($file).’" data-bs-toggle="tab" data-bs-target="#content-’.basename($file).’" role="tab">’.basename($file).’</button>’;
            echo ’</li>’;
        }
        echo ’</ul>’;
        
        echo ’<div class="tab-content mt-3">’;
        foreach ($this->files as $index => $file) {
            $code = htmlspecialchars(file_get_contents($file));
            $lang = $this->getLanguage($file);
            echo ’<div class="tab-pane fade ’.($index === 0 ? ’show active’ : ’’).’" id="content-’.basename($file).’" role="tabpanel">’;
            echo ’<h5>Description</h5><p>’.htmlspecialchars($this->descriptions[$file]).’</p>’;
            echo ’<h5>Code</h5><pre><code class="’ . $lang . ’ line-numbers">’.$code.’</code></pre>’;
            echo ’<button class="btn btn-primary mt-2 run-code" data-file="’.$file.’">Виконати</button>’;
            echo ’<h5>Output</h5><pre id="output-’.basename($file).’" class="bg-light p-2"></pre>’;
            echo ’</div>’;
        }
        echo ’</div>’;
        
        echo ’<script>
            document.getElementById("themeSelector").addEventListener("change", function() {
                let selectedTheme = this.value;
                let linkTag = document.querySelector("link[rel=stylesheet]");
                let themeLinks = ’.json_encode($this->themes).’;
                linkTag.href = themeLinks[selectedTheme];
            });
            
            document.querySelectorAll(".run-code").forEach(button => {
                button.addEventListener("click", function() {
                    let file = this.getAttribute("data-file");
                    let outputDiv = document.getElementById("output-" + file.split("/").pop());
                    fetch("execute.php", {
                        method: "POST",
                        headers: { "Content-Type": "application/x-www-form-urlencoded" },
                        body: "file=" + encodeURIComponent(file)
                    })
                    .then(response => response.text())
                    .then(output => { outputDiv.textContent = output; })
                    .catch(error => { outputDiv.textContent = "Error executing file"; });
                });
            });
        </script>’;
        
        echo ’<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>’;
        echo ’</body></html>’;
    }
}

// Використання
try {
    $editor = new CodeEditor();
    $editor->addExample("k2test.php", "Цей приклад виводить ’Hello, World!’");
    $editor->addExample("k2test_phpgrid_demogrid.php", "Цей приклад показує арифметичні операції");
    $editor->setTheme("dark"); // Встановлення теми за замовчуванням
    $editor->render();
} catch (Exception $e) {
    echo "Error: " . $e->getMessage();
}

Скриншот рішення:

Чому це важливо?

Цей код є спрощеним рішенням, яке кожен розробник може використати у себе для тестування PHP-коду. Воно працює автономно та не потребує складних налаштувань.

Водночас у K2 Cloud ERP реалізовано більш потужне рішення, яке дозволяє не лише виконувати код, а й працювати з великою кількістю прикладів. Ці приклади постійно доповнюються та розширюються, даючи можливість розробникам швидше інтегрувати готові рішення у свої проєкти.


    Runtime Site: 3.887324 s.