如何在PHP网站中实现类似Stack Overflow的文本+代码混合编辑器?
我正在开发一个PHP网站,需实现包含视频+代码的教程板块。最初在textarea中输入PHP代码无法正常显示,使用htmlspecialchars结合<pre>标签解决了纯代码显示问题,但无法支持文本与代码混合内容。请问如何实现类似Stack Overflow的编辑器,支持文本与代码混合编写?
以下是我的添加页面(ADDPAGE)和展示页面(DISPLAY PAGE)的代码:
ADDPAGE
<?php session_start(); ?> <?php include("../connessione.php"); if(isset($_SESSION['competenze'])) { $result = mysqli_query($connessione, "SELECT * FROM amministratore"); ?> <!-- FINE CONTROLLO DELLA SESSIONE --> <?php include("header-articoli.php");?> <?php // IMPLEMENTIAMO LA VARIABILE MESSAGGIO $messaggio = ""; if (isset($_POST['submit'])) { include '../../connessione.php'; //REAL_ESCAPE_STRING ANTI STRINGA BUCA DB $titolo = $connessione->real_escape_string($_POST['titolo']); $descrizione = $connessione->real_escape_string($_POST['descrizione']); $contenuto = $connessione->real_escape_string($_POST['contenuto']); // IMPLEMENTA PASSWORD_HASH PER INNALZAMENTO SICUREZZA PHP VERSION 5.6 MAGGIORE $connessione->query("INSERT INTO wp (titolo,descrizione,contenuto) VALUES ('$titolo', '$descrizione', '$contenuto')"); $messaggio = "Articolo in Wordpress correttamente inserito!"; } ?> <div style="text-align: center;padding-top: 0px;" class="container"> <div class="row"> <div class="col-md-3"></div> <div class="col-md-6"> <?php if ($messaggio != "") echo "<img src='../immagini/wordpress.png' style='max-width: 15%;max-height: 15%;'" . '<br><br><br>' . $messaggio . '<br><br><br>' ; ?> <form method="post" action="aggiungi-wp.php"> <input class="form-control" minlength="3" name="titolo" placeholder="Titolo"><br> <textarea name="descrizione" rows="3" cols="40" placeholder="Descrizione" style="width: 100%;border: 1px solid #000;"></textarea> <textarea name="contenuto" rows="30" cols="40" placeholder="Contenuto" style="width: 100%;border: 1px solid #000;"></textarea> <input class="btn btn-primary" name="submit" type="submit" value="Pubblica"><br> </form> </div> <div class="col-md-3"></div> </div> </div> <!-- FINE CONTENUTO SE LA CONDIZIONE E' VERA --> <?php }else{ ?> Contenuto non accesisbile, gentilmente esegui il login per entrare nella tua area privata. Grazie <!-- FINE CONTENUTO SE LA CONDIZIONE E' FALSA --> <?php } ?>
DISPLAY PAGE
<?php include("header-dettagli.php"); ?> <?php session_start(); include_once '../../connessione.php'; $id = $_GET['id']; $query_string = "SELECT * FROM wp WHERE id='$id'"; $query = mysqli_query($connessione, $query_string); ?> <div style="text-align: ;" class="container"> <div class="row"> <?php while($row = mysqli_fetch_assoc($query)){ ?> <div style="padding-bottom: 30px;" class="col-md-12"> <h3><?php echo $row['titolo'] ;?></h3> <p><?php echo $row['descrizione'] ;?></p> </div> <div class="col-md-12"> <?php $code = $row['contenuto'] ; echo '<pre>' . htmlspecialchars($code) . '</pre>'; ?> </div> <?php } ?> </div> </div>
嘿,我来帮你解决这个问题!你现在遇到的核心问题是纯文本编辑器无法区分普通内容和代码块,Stack Overflow这类平台的思路是用**标记语言(比如Markdown)**让用户明确区分内容类型,再在展示时解析成对应的HTML。下面给你两种可行方案,从快速实现到专业级都有:
方案1:集成Markdown编辑器(最推荐,和Stack Overflow体验一致)
这是最成熟的方案,用户用Markdown语法编写,你只需负责存储和解析即可。
步骤1:替换textarea为Markdown编辑器
选一个轻量的开源编辑器,比如SimpleMDE,它的界面和Stack Overflow很像。在你的ADDPAGE里做如下修改:
<!-- 在<head>标签里引入编辑器的CSS和JS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css"> <script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script> <!-- 替换原来的contenuto textarea --> <textarea name="contenuto" rows="30" cols="40" placeholder="Contenuto(支持Markdown:代码块用```包裹,比如```php ... ```)" style="width: 100%;border: 1px solid #000;"></textarea> <!-- 初始化编辑器 --> <script> var simplemde = new SimpleMDE({ element: document.getElementsByName("contenuto")[0], toolbar: ["bold", "italic", "heading", "|", "code", "quote", "unordered-list", "ordered-list", "|", "preview", "fullscreen"] }); </script>
这样用户就能直观地插入代码块、加粗文本、添加列表等,和Stack Overflow的编辑体验一致。
步骤2:存储与展示解析
- 存储:不需要额外修改你的插入逻辑,继续用
real_escape_string防止SQL注入,直接把用户输入的Markdown内容存入数据库即可。 - 展示:用PHP的Markdown解析库把Markdown转换成HTML,推荐轻量级的
Parsedown:// 先下载Parsedown.php(官网可以免费获取),然后引入 include 'Parsedown.php'; $parsedown = new Parsedown(); // 开启代码块的HTML类支持,方便后续加高亮 $parsedown->setMarkupEscaped(true); $parsedown->setBreaksEnabled(true); // 把数据库里的Markdown内容转换成HTML $contenutoHtml = $parsedown->text($row['contenuto']); // 直接输出即可,Parsedown会自动处理代码块的转义和标签生成 echo $contenutoHtml;
额外优化:代码高亮
给代码块加上语法高亮,和Stack Overflow一样美观。引入Prism.js:
<!-- 在展示页面的<head>里引入 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism.min.css"> <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.min.js"></script> <!-- 引入PHP语言包,支持PHP代码高亮 --> <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-php.min.js"></script>
用户在Markdown里写```php ... ```,Parsedown会生成带class="language-php"的<code>标签,Prism会自动高亮代码。
方案2:自定义简单标记(快速临时方案)
如果不想引入第三方编辑器,可以自己定义标记让用户区分代码和文本,比如用[code]和[/code]包裹代码块。
步骤1:提示用户使用标记
修改ADDPAGE里的textarea placeholder:
<textarea name="contenuto" rows="30" cols="40" placeholder="Contenuto(代码块用[code]和[/code]包裹)" style="width: 100%;border: 1px solid #000;"></textarea>
步骤2:展示页面解析标记
在DISPLAY PAGE里替换原来的代码输出逻辑,改成解析标记:
$contenuto = $row['contenuto']; // 分割内容并处理代码块 $parts = preg_split('/(\[code\]|\[\/code\])/', $contenuto, -1, PREG_SPLIT_DELIM_CAPTURE); $htmlOutput = ''; $isCodeBlock = false; foreach ($parts as $part) { if ($part == '[code]') { $isCodeBlock = true; $htmlOutput .= '<pre><code>'; } elseif ($part == '[/code]') { $isCodeBlock = false; $htmlOutput .= '</code></pre>'; } else { if ($isCodeBlock) { // 代码块转义特殊字符 $htmlOutput .= htmlspecialchars($part); } else { // 普通文本保留换行 $htmlOutput .= nl2br(htmlspecialchars($part)); } } } echo $htmlOutput;
这种方式比较简陋,没法处理复杂格式,适合临时应急用,长期还是推荐Markdown方案。
内容的提问来源于stack exchange,提问作者user9778900

