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>名稱    </th>
<th>型別    </th>
<th>大小    </th>
<th>操作    </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 ' <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 ' <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
-
註冊登入Packagist(https://packagist.org/)
-
點選右上角Submit
-
將你的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