php动态高亮web源代码

文章介绍了如何使用PHP实现动态展示目录树结构的源代码,强调了配置安全规则以防止高亮敏感文件,以及结合HTML缓存以提高性能。
摘要由CSDN通过智能技术生成

php动态高亮web源代码

注:配置好不允许高亮的文件名,安全第一

#php实现动态展示目录树结构源代码

适用于开放源代码,结合html缓存使用效果更佳,因循环较多不适合放首页

能力有限没实现行号

演示:show source|开放源代码

效果截图

代码

4个文件放统一目录

1.php,1.html,net.js,showsource.php

1.php

<?php
header('Content-Type: text/html; charset=utf-8');

define('root',str_replace('\\','/',realpath(__DIR__.'/../..')));
$dir = root;
$res = [];
$root_dir = $dir;
$res = tree($res,$dir);
//$res = preg_replace('/^'.preg_quote($dir,'/').'/', 'root', $res);
$data = base64_encode(json_encode($res));
require '1.html';
function tree(&$res,$dir)
{
    global $root_dir;
    if(count($res)===0){
        $res[]=[
            'id'=>sha1($dir),
            'pid'=>0,
            'type'=>'dir',
            'handle'=>$dir,
            'name'=>substr($dir,strripos($dir,'/')+1,strlen($dir)),
        ];
    }
    $handles = array_merge(glob($dir . '/.*'), glob($dir . '/*'));
    $handles = preg_replace('/^[\s\S]*\/\.$/','',$handles);
    $handles = preg_replace('/^[\s\S]*\/\.\.$/','',$handles);
    $handles = array_filter($handles);
    sort($handles);
    foreach ($handles as $item){
        if(is_dir($item)){
            $res[]=[
                'id'=>sha1($item),
                'pid'=>sha1($dir),
                'type'=>'dir',
                'handle'=>preg_replace('/^'.preg_quote($root_dir,'/').'/','root',$item),
                'name'=>substr($item,strripos($item,'/')+1,strlen($item)),
            ];
            tree($res,$item);
        }else{
            $res[]=[
                'id'=>sha1($item),
                'pid'=>sha1($dir),
                'type'=>'file',
                'handle'=>preg_replace('/^'.preg_quote($root_dir,'/').'/','root',$item),
                'name'=>substr($item,strripos($item,'/')+1,strlen($item)),
            ];
        }
    }
    return $res;
}

function dump($s=null,$return = false)
{
    ob_start();
    var_dump($s);
    $res = ob_get_clean();
    $res = preg_replace('/'.preg_quote(']=>','/').'\n[\s]+/m', '] => ', $res);
    switch (php_sapi_name()){
        case 'cgi-fcgi':
            $res = preg_replace('/  /U', "\t", $res);
            $res = '<pre><code>'.$res.'</code></pre>';
            if($return)
                return $res;
            echo $res;
            break;
        case 'cli':
            if($return)
                return $res;
            echo $res;
            break;
    }
}

1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>show source|开放源代码</title>
    <style>

        .my-tree {
            line-height: 20px;
        }

        .my-tree li::marker {
            content: '';
        }

        .my-tree summary::marker {
            content: '';
        }

        .my-tree ul {
            margin: 0;
            font-size: 0;
        }

        .my-tree li {
            position: relative;
        }

        .my-tree details {

        }

        .my-tree summary {
            position: relative;
            display: block;
            padding-left: 20px;
            cursor: pointer;
            font-size: 16px;
        }

        .my-tree li a {
            position: relative;
            display: block;
            padding-left: 20px;
            cursor: pointer;
            font-size: 16px;
            text-decoration: none;
            color: #222222;
        }

        .my-tree summary::before {
            content: '+';
            display: block;
            position: absolute;
            text-align: center;
            width: 18px;
            height: 18px;
            line-height: 18px;
            left: 0;
            top: 0;
            border-radius: 50%;
            z-index: 1;
            background: #696;
            color: #fff;
            cursor: pointer;
            border: 1px solid #ddd;
            font-size: 16px;
        }

        .my-tree li a::before {
            content: "";
            display: block;
            position: absolute;
            text-align: center;
            width: 18px;
            height: 18px;
            line-height: 18px;
            left: 0;
            top: 0;
            border-radius: 50%;
            z-index: 1;
            background: #ddd;
            color: #fff;
            cursor: pointer;
            border: 1px solid #ddd;
            font-size: 16px;
        }

        .my-tree details {
            position: relative;
        }

        .my-tree li {
            display: block;
            position: relative;
            border-left: 2px solid #ddd;
            padding-left: 18px;
            margin-left: -31px;
        }

        .my-tree ul li::before {
            content: '';
            display: block;
            position: absolute;
            top: -8px;
            left: -2px;
            width: 18px;
            height: 18px;
            border: solid #ddd;
            border-width: 0 0 2px 2px;
        }

        .my-tree details[open] > summary::before {
            content: '−';
        }

        .my-tree .active a::before {
            background: #696;
        }

        .my-tree .active a {
            color: #0a67fb;
        }

        .my-tree summary:hover {
            color: royalblue;
        }

        .my-tree a:hover {
            color: royalblue;
        }

        .my-tree li:last-child {
            border-color: transparent;
        }
        .left {
            background: #eee;
            display: inline-block;
            width: 30%;
            float: left;
        }

        .right {
            display: inline-block;
            width: 70%;
            float: left;
        }
        .source-text{
            width: 100%;
            height: 500px;
            resize: vertical;
            border: 1px solid rgba(0,0,0,0.2);
            outline: unset;
        }
    </style>
</head>
<body>
<div class="main">
    <div class="left">
        <div class="file-menu">
            <div id="file-list" class="my-tree">
            </div>
        </div>
    </div>
    <div class="right">
        <div class="source">
            <textarea class="source-text" id="source"></textarea>
        </div>
    </div>

</div>
<script src="/static/js/net.js"></script>
<script>
    hljsload = false;
    net = new Net();
    let data = "<?php echo $data; ?>";
    data = JSON.parse(atob(data));
    let  tree = treeFile(data);
    initFileList(tree);

    function showSource(obj) {
        document.querySelectorAll('#file-list .active').forEach(function (active) {
            active.classList.remove('active');
        });
        obj.parentElement.classList.add('active');
        let post_data = {file: obj.dataset.file};
        net.post('showsource.php', 'data=' + JSON.stringify(post_data), function (data) {
            data = JSON.parse(data);
            if (data.code !== 200) {
                document.getElementById("source").textContent = data.msg;
                return;
            }
            document.getElementById("source").textContent = decodeURIComponent(data.data);
        });
    }

    function treeFile(data) {
        for (let i = 0; i < data.length; i++) {
            data[i].childnodes = [];
            data[i].list = [];
            for (let j = 0; j < data.length; j++) {
                if (data[j].pid === data[i].id) {
                    switch (data[j].type) {
                        case 'dir':
                            data[i].childnodes.push(data[j]);
                            break;
                        case 'file':
                            data[i].list.push(data[j]);
                            break;
                    }
                }
            }
        }
        return data[0];
    }

    function initFileList(data) {
        var ul = '';
        ul = getFileList(data, ul);
        document.getElementById("file-list").innerHTML = ul;
        document.querySelectorAll('#file-list a').forEach(function (link) {
            link.addEventListener('click', function (event) {
                event.preventDefault();
                showSource(link);
            });
        });
    }


    function getFileList(obj, ul) {
        if (ul === '') {
            ul += '<details open>';
            ul += '<summary>' + obj.name + '</summary>';
            ul += '<ul>';
            if (!(obj.childnodes.length === 0)) {
                for (let key in obj.childnodes) {
                    ul = getFileList(obj.childnodes[key], ul);
                }
            }

            if (!(obj.list.length === 0)) {
                for (let key in obj.list) {
                    ul += '<li><a href="#" data-file="' + obj.list[key].handle + '">' + obj.list[key].name + '</a></li>';
                }
            }
            ul += '</ul>';
            ul += '</details>';
            return ul;
        } else {
            ul += '<li>';
            ul += '<details>';
            ul += '<summary>' + obj.name + '</summary>';
            ul += '<ul>';
            if (!(obj.childnodes.length === 0)) {
                for (let key in obj.childnodes) {
                    ul = getFileList(obj.childnodes[key], ul);
                }
            }

            if (!(obj.list.length === 0)) {
                for (let key in obj.list) {
                    ul += '<li><a href="#" data-file="' + obj.list[key].handle + '">' + obj.list[key].name + '</a></li>';
                }
            }
            ul += '</ul>';
            ul += '</details>';
            ul += '</li>';
            return ul;
        }

    }

</script>
</body>
</html>

net.js

function Net() {
    this.xhr = new XMLHttpRequest();
    this.get = function (url, func, pram = {}) {
        xhr = this.xhr;
        xhr.onreadystatechange = function () {
            if (this.readyState == 4) {
                pram.code = this.status;
                if (this.status == 200) {
                    func(this.responseText, pram);
                } else {
                    func(this.responseText, pram);
                }
            }
        };
        xhr.open('get', url, false);
        xhr.send()
    };
    this.post = function (url, data, func,pram = {}) {
        xhr = this.xhr;
        xhr.onreadystatechange = function () {
            if (this.readyState == 4) {
                pram.code = this.status;
                if (this.status == 200) {
                    func(this.responseText,pram);
                } else {
                    func(this.responseText,pram);
                }
            }
        };
        xhr.open("POST", url, false);
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.send(data)
    }
}

showsource.php

<?php
header('Content-Type: text/html; charset=utf-8');

if(empty($_POST['data'])){
    die;
}
$data = $_POST['data'];
$data = json_decode($data,true);
if(empty($data['file'])){
    die;
}

define('root',str_replace('\\','/',realpath(__DIR__.'/../..')));
$dir = root;
$root_dir = $dir;

$pass_files = [
    'root/app/conf.php',
];
$allow_ext = [
    'html','js','css','php','txt','xml','json',
];

$file = $data['file'];

if(in_array($file,$pass_files)){
    outSource(500,'涉及配置不允许高亮','');
    die;
}
if(strpos($file,'.')!==false){
    $file_ext = substr($file,strripos($file,'.')+1,strlen($file));
    if(!in_array($file_ext,$allow_ext)){
        outSource(500,'只允许高亮'.implode('|',$allow_ext).'后缀文件','');
        die;
    }
}

$file = preg_replace('/^root/',$root_dir,$file);
if(!is_file($file)){
    outSource(500,'文件不存在','');
    die;
}

$code = highlight_file($file,true);
outSource(200,'',$code);

function outSource($code,$msg,$data)
{
    echo json_encode([
        'code'=>$code,
        'msg'=>$msg,
        'data'=>$data,
    ],JSON_UNESCAPED_UNICODE);
}

注:配置好不允许高亮的文件名,安全第一

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

etafort

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值