• 基于Composer的Laravel扩展包开发工作流 ,实现laravle项目的文件管理(记录成长)


    PHP Composer包开发

    基于Composer的Laravel扩展包开发工作流

    实现laravle项目的文件管理,添加文件/文件夹,删除文件,查看代码/文件(代码支持缩进,支持语法高亮)

    composer 项目地址:https://packagist.org/packages/wuqb/laravel-codeview

    github 项目地址: https://github.com/wuxiumu/code-management

    1、在项目下执行

    mkdir packages // 创建packages 目录 cd packages // 进入 packages 目录 mkdir code-management // 创建code-management 目录,准备开发laravle文件管理

    项目目录结构

    - code-management --config --codemirror-5.31.0 [前端文件包] --codeview.php [配置名称,路由,登录密码的] --routes --codevew.php [codeview 路由地址] --src [开发包] --Faceds --CodeView.php --CodeView.php --CodeViewProvider.php --composer.json

    2、修改composer.json 文件

    "autoload-dev": { "psr-4": { "App\\": "app/" } },

    修改后

    "autoload-dev": { "psr-4": { "App\\": "app/", "Wqb\\CodeView\\": "packages/code-management/src" } },

    3、执行 composer命令

    composer dump_autoload

    4、添加包的ServiceProvider

    由于laravel的 package:discover 是读取 vendor/composer/installed.json 这个文件中安装的包,而我们的包是手动添加,所以无法自动添加ServiceProvider,手动在app.php中添加

    'providers' => [ Wqb\CodeView\CodeViewProvider::class ], 'aliases' => [ 'CodeView' => Wqb\CodeView\Facades\CodeView::class ],

    上代码

    code-management/composer.json

    { "name": "wuqb/laravel-codeview", "description": "laravel codeview", "license": "MIT", "authors": [ { "name": "wuqb", "email": "824543976@qq.com" } ], "autoload": { "psr-4": { "Wqb\\CodeView\\": "src" } }, "require": {} }

    code-management/config/codeview.php

    <?php return [ 'name' => '简单的线上代码管理工具', 'password' => 'tk12', 'route' => '/codeview', ];

    code-management/routes/codeview.php

    <?php Route::any('codeview','\Wqb\CodeView\CodeView@index');

    code-management/src/Faceds/CodeView.php

    <?php namespace Wqb\CodeView\Facades; use Illuminate\Support\Facades\Facade; class CodeView extends Facade { protected static function getFacadeAccessor() { return 'codeview'; } }

    code-management/src/CodeView.php

    <?php namespace Wqb\CodeView; use Illuminate\Config\Repository; use Illuminate\Http\Request; class CodeView { protected $config; /** * 构造方法 */ public function __construct(Repository $config) { $this->config = $config->get('codeview'); } /** * 展示页 */ public function index(Request $request) { $this->head(); $this->viewAction($request); $this->foot(); } /** * 展示处理 */ public function viewAction($request) { $password = $this->config['password']; $n = $this->config['route']; $csrf_token = csrf_token(); if (isset($_COOKIE['filehelper_login_password_123456789']) && $_COOKIE['filehelper_login_password_123456789'] == md5($password)) { $c = $request->input('c'); $v = $request->input('v'); $a = $request->input('a'); $b = $request->input('b'); $v1 = './' . $v; $va = $v1 . $a; echo '<h3>' . $this->config['name'] . '</h3>'; switch ($c) { case 'del': if (is_file($va) == true) { unlink($va); echo "成功删除" . $a . "!"; } else { echo "文件已经被删除!"; } break; case 'up': if ($_FILES["file"]["error"] > 0) { echo "上传失败! 错误码:" . $_FILES["file"]["error"] . "<br>"; } else { if (file_exists($v1 . $_FILES["file"]["name"])) { echo "文件已经存在。 "; } else { move_uploaded_file($_FILES["file"]["tmp_name"], $v1 . $_FILES["file"]["name"]); echo "上传成功!"; } } break; case 'md': if ($a != "") { if (is_dir($va)) { echo "文件夹已存在!"; } else { mkdir($va); echo '文件夹创建成功!'; } } else { echo "文件夹名不能为空!"; } break; case 'ed': if ($request->input('s') == "1") { $eded = fopen($va, 'w'); fwrite($eded, $_POST['fs']); fclose($eded); echo '<h3>保存成功!</h3>'; } else { echo '<a href="' . $n . '?v=' . $v . '">返回</a><br> <form action="' . $n . '?v=' . $v . '&a=' . $a . '&c=ed&s=1" method="post" enctype="multipart/form-data"> <textarea type="text" name="fs" id="ed">' . str_replace('</textarea>', '</ t e xtarea>', file_get_contents($va)) . '</textarea></br> <input type="hidden" name="_token" value="'.$csrf_token.'"> <button type="submit">保存</button></form>'; } break; default: # code... break; } // 编辑页面是否展示列表 if ($b == "1") { } else { echo '<a href="' . $n . '?v=' . dirname($v) . '/">返回</a><br> <table><tr> <th>名称&emsp;&emsp;&emsp;&emsp;</th> <th>类型&emsp;&emsp;&emsp;&emsp;</th> <th>大小&emsp;&emsp;&emsp;&emsp;</th> <th>操作&emsp;&emsp;&emsp;&emsp;</th> </tr> '; if (is_dir($v1) == true) { $fs = scandir($v1); $i = 2; while ($i <= count($fs) - 1) { if ($fs[$i] != $n) { echo "<tr><td>" . $fs[$i] . "</td>"; if (is_dir($v1 . $fs[$i]) == true) { echo "<td>文件夹</td>"; echo "<td>-</td>"; echo '<td><a href=' . $n . '?v=' . $v . $fs[$i] . '/>打开</a></td>'; } if (is_file($v1 . $fs[$i]) == true) { echo "<td>文件</td>"; echo "<td>" . number_format(filesize($v1 . $fs[$i]) / 1024 / 1024, 4, ".", "") . "MB</td>"; if (substr(strrchr($fs[$i], '.'), 1) !== 'php' && substr(strrchr($fs[$i], '.'), 1) !== 'asp' && substr(strrchr($fs[$i], '.'), 1) !== 'aspx' && substr(strrchr($fs[$i], '.'), 1) !== 'do') { echo '<td><a href="' . $v . $fs[$i] . '">下载</a>'; } else { echo '<td><a href="' . $v . $fs[$i] . '">打开</a>'; } echo '&nbsp;<a href="' . $n . '?c=del&a=' . $fs[$i] . '&v=' . $v . '">删除</a>'; $ihzm = substr(strrchr($fs[$i], '.'), 1); if ($ihzm !== 'png' && $ihzm !== 'doc' && $ihzm !== 'docx' && $ihzm !== 'jpg' && $ihzm !== 'gif' && $ihzm !== 'zip' && $ihzm !== 'apk' && $ihzm !== 'webp' && $ihzm !== 'ppt' && $ihzm !== 'pptx' && $ihzm !== 'exe' && $ihzm !== 'xls') { echo '&nbsp;<a href="' . $n . '?c=ed&v=' . $v . '&a=' . $fs[$i] . '&b=1">编辑</a>'; } echo '</td>'; } echo "</tr>"; } $i++; } } echo '</table><hr> <form action="' . $n . '?v=' . $v . '&c=up" method="post" enctype="multipart/form-data"> 上传文件:<input type="file" name="file"> <input type="hidden" name="_token" value="'.$csrf_token.'"> <input type="submit" value="上传"> </form> <form action="' . $n . '" method="get" enctype="multipart/form-data"> <input type="hidden" name="_token" value="'.$csrf_token.'"> 新建文件夹:<input type="text" name="a"><input type="hidden" name="c" value="md"><input type="hidden" name="v" value="' . $v . '"> <input type="submit" value="新建"> </form>'; } } else { if ($request->input('password') == $password) { setcookie("filehelper_login_password_123456789", md5($password), time() + 3600); header("location:" . $n); } else { $this->form(); } } } /** * 登录文件管理验证 */ public function form() { $csrf_token=csrf_token(); echo <<<EOF <form action="" method="post" enctype="multipart/form-data"> 请输入密码 <input type="hidden" name="_token" value="$csrf_token"> <input type="password" name="password"> <input type="submit" value="登录"> </form> EOF; } /** * 头部 * 引入必要的js,css */ public function head() { echo <<<EOF <!DOCTYPE html> <html lang="en"> <!--begin code mirror --> <!--下面两个是使用Code Mirror必须引入的--> <link rel="stylesheet" href="/src/codemirror-5.31.0/lib/codemirror.css" /> <script src="/src/codemirror-5.31.0/lib/codemirror.js"></script> <!--Java代码高亮必须引入--> <script src="/src/codemirror-5.31.0/clike.js"></script> <!--groovy代码高亮--> <script src="/src/codemirror-5.31.0/mode/groovy/groovy.js"></script> <!--引入css文件,用以支持主题--> <link rel="stylesheet" href="/src/codemirror-5.31.0/theme/dracula.css" /> <!--支持代码折叠--> <link rel="stylesheet" href="/src/codemirror-5.31.0/addon/fold/foldgutter.css" /> <script src="/src/codemirror-5.31.0/addon/fold/foldcode.js"></script> <script src="/src/codemirror-5.31.0/addon/fold/foldgutter.js"></script> <script src="/src/codemirror-5.31.0/addon/fold/brace-fold.js"></script> <script src="/src/codemirror-5.31.0/addon/fold/comment-fold.js"></script> <!--括号匹配--> <script src="/src/codemirror-5.31.0/addon/edit/matchbrackets.js"></script> <!--end Code Mirror --> <head> <meta charset="utf-8" /> <title>文件管理</title> </head> EOF; } /** * 脚部 * js 配置:代码折叠 | 设置主题 | 代码高亮| 设置代码框的长宽 */ public function foot() { echo <<<EOF <script> var editor = CodeMirror.fromTextArea(document.getElementById("ed"), { mode: "text/groovy", //实现groovy代码高亮 mode: "text/x-java", //实现Java代码高亮 lineNumbers: true, //显示行号 theme: "dracula", //设置主题 lineWrapping: true, //代码折叠 foldGutter: true, gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"], matchBrackets: true, //括号匹配 //readOnly: true, //只读 }); editor.setSize('100%', '400px'); //设置代码框的长宽 </script> </body> </html> EOF; } }

    code-management/src/CodeViewProvider.php

    <?php namespace Wqb\CodeView; use Illuminate\Support\ServiceProvider; class CodeViewProvider extends ServiceProvider { /** * Bootstrap the application services. * * @return void */ public function boot() { $this->loadRoutesFrom(__DIR__.'/../routes/codeview.php'); $this->publishes([ __DIR__.'/../config/codemirror-5.31.0' => base_path('public/src/codemirror-5.31.0'), ]); } /** * Register the application services. * * @return void */ public function register() { $this->app->singleton('codeview', function ($app) { return new CodeView($app['config']); }); } }

    5、访问项目地址/codeview

    登录页
    密码:

    tk12

    列表页

    查看编辑页

    文件上传,新建目录

    6、提交推送到git仓库

    不懂可以百度,如何提交代码到github仓库

    7、发布到packagist

    1. 注册登录Packagist(https://packagist.org/

    2. 点击右上角Submit

    3. 将你的Github地址贴进去,点Check

    8、可能遇到的问题

    1、Could not find a version of package matching your minimum-stability (stable).

    git tag v1.0 git push origin v1.0

    2、Could not find package

    // 不要使用国内镜像,设置回 https://packagist.org // 然后别忘了打开你的梯子 composer config -g repo.packagist composer https://packagist.org

    __EOF__

    本文作者wuxiumu
    本文链接https://www.cnblogs.com/wuxiumu/p/16136039.html
    关于博主:评论和私信会在第一时间回复。或者直接私信我。
    版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
    声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
  • 相关阅读:
    Kafka生产者使用案例
    速盾:ddos高防ip原理
    K8S容忍toleration的声明语法、配置项含义及和污点的配合使用
    Svelte框架结合SpreadJS实现表格协同文档
    【开源】基于SpringBoot的高校学院网站的设计和实现
    Presto 聚合中groupBy分组的实现
    开发多点触控MFC应用程序
    弗洛伊德算法(C++)
    巧用Jmeter Debug sampler获取变量信息
    智能BI,如今走到了哪一步?
  • 原文地址:https://www.cnblogs.com/wuxiumu/p/16136039.html