現(xiàn)在laravel和thinkphp還有webman,其實區(qū)別不是特別大了,能不能寫一個遷移工具,方便遷移這兩個項目代碼到webman?
<?php
namespace app\tool\controller;
use support\Request;
class LaravelToWebmanController
{
private $laravelPath;
private $webmanPath;
public function __construct($laravelPath, $webmanPath)
{
$this->laravelPath = $laravelPath;
$this->webmanPath = $webmanPath;
}
public function convertControllers()
{
$laravelCodeDir = $this->laravelPath . '/app/Http/Controllers';
$webmanCodeDir = $this->webmanPath . '/app/Http/Controllers/Webman';
$files = scandir($laravelCodeDir);
foreach ($files as $file) {
if ($file === '.' || $file === '..') {
continue;
}
$laravelFilePath = $laravelCodeDir . '/' . $file;
$webmanFilePath = $webmanCodeDir . '/' . $file;
$laravelCode = file_get_contents($laravelFilePath);
$webmanCode = $this->convertLaravelToWebman($laravelCode, 'controller');
file_put_contents($webmanFilePath, $webmanCode);
}
echo 'Controller轉(zhuǎn)換完成!';
}
public function convertModels()
{
$laravelModelDir = $this->laravelPath . '/app/Models';
$webmanModelDir = $this->webmanPath . '/app/Models/Webman';
$files = scandir($laravelModelDir);
foreach ($files as $file) {
if ($file === '.' || $file === '..') {
continue;
}
$laravelFilePath = $laravelModelDir . '/' . $file;
$webmanFilePath = $webmanModelDir . '/' . $file;
$laravelCode = file_get_contents($laravelFilePath);
$webmanCode = $this->convertLaravelToWebman($laravelCode, 'model');
file_put_contents($webmanFilePath, $webmanCode);
}
echo 'Model轉(zhuǎn)換完成!';
}
public function convertViews()
{
$laravelViewDir = $this->laravelPath . '/resources/views';
$webmanViewDir = $this->webmanPath . '/resources/views';
$files = scandir($laravelViewDir);
foreach ($files as $file) {
if ($file === '.' || $file === '..') {
continue;
}
$laravelFilePath = $laravelViewDir . '/' . $file;
$webmanFilePath = $webmanViewDir . '/' . $file;
$laravelCode = file_get_contents($laravelFilePath);
$webmanCode = $this->convertLaravelToWebman($laravelCode, 'view');
file_put_contents($webmanFilePath, $webmanCode);
}
echo 'View轉(zhuǎn)換完成!';
}
public function convertRoutes()
{
$laravelRouteFile = $this->laravelPath . '/routes/web.php';
$webmanRouteFile = $this->webmanPath . '/config/routes.php';
$laravelCode = file_get_contents($laravelRouteFile);
$webmanCode = $this->convertLaravelToWebman($laravelCode, 'route');
file_put_contents($webmanRouteFile, $webmanCode);
echo '路由轉(zhuǎn)換完成!';
}
private function convertLaravelToWebman($laravelCode, $type)
{
// 在這里實現(xiàn)將Laravel代碼轉(zhuǎn)換為Webman代碼的邏輯
// 這個函數(shù)應(yīng)該根據(jù)Laravel和Webman的不同結(jié)構(gòu)進行相應(yīng)的轉(zhuǎn)換
// 請根據(jù)實際情況自行編寫
// 這里只是一個示例,可能并不適用于你的項目
if ($type === 'controller') {
$webmanCode = $this->replaceLaravelController($laravelCode);
} elseif ($type === 'model') {
// 進行Model轉(zhuǎn)換邏輯...
$webmanCode = $this->replaceLaravelModel($laravelCode);
} elseif ($type === 'view') {
// 進行View轉(zhuǎn)換邏輯...
$webmanCode = $this->replaceLaravelBladeSyntax($laravelCode);
} elseif ($type === 'route') {
// 進行Route轉(zhuǎn)換邏輯...
$webmanCode = $this->replaceLaravelRoutes($laravelCode);
} else {
$webmanCode = '';
}
return $webmanCode;
}
private function replaceLaravelModel($laravelCode)
{
$webmanCode = str_replace('namespace App\Models;', 'namespace app\model;', $laravelCode);
// 替換基類
$webmanCode = str_replace('use Illuminate\Database\Eloquent\Model;', 'use support\Model;', $webmanCode);
// 進行其他模型轉(zhuǎn)換邏輯...
return $webmanCode;
}
private function replaceLaravelBladeSyntax($code)
{
// 替換Laravel的Blade語法為Webman視圖語法
$search = [
'/{{\s*([^}]*)\s*}}/', // 替換 {{ $variable }} 為 <?= $variable
'/{!!\s*([^}]*)\s*!!}/', // 替換 {!! $variable !!} 為 <?= $variable
'/@if\s*\(([^)]*)\)/', // 替換 @if(condition) 為 <?php if (condition):
'/@elseif\s*\(([^)]*)\)/', // 替換 @elseif(condition) 為 <?php elseif (condition):
'/@else/', // 替換 @else 為 <?php else:
'/@endif/', // 替換 @endif 為 <?php endif;
// 可以根據(jù)需要添加其他的替換規(guī)則...
];
$replace = [
'<?php echo $1; ?>',
'<?php echo $1; ?>',
'<?php if ($1): ?>',
'<?php elseif ($1): ?>',
'<?php else: ?>',
'<?php endif; ?>',
// 添加其他的替換結(jié)果...
];
$webmanCode = preg_replace($search, $replace, $code);
return $webmanCode;
}
private function replaceLaravelRoutes($code)
{
// 替換Laravel的路由定義為Webman路由定義
$search = [
'/Route::get\s*\(([^)]*)\)/', // 替換 Route::get(...) 為 get(...)
'/Route::post\s*\(([^)]*)\)/', // 替換 Route::post(...) 為 post(...)
'/Route::put\s*\(([^)]*)\)/', // 替換 Route::put(...) 為 put(...)
'/Route::patch\s*\(([^)]*)\)/', // 替換 Route::patch(...) 為 patch(...)
'/Route::delete\s*\(([^)]*)\)/', // 替換 Route::delete(...) 為 delete(...)
'/Route::any\s*\(([^)]*)\)/', // 替換 Route::any(...) 為 any(...)
'/Route::match\s*\(([^)]*)\)/', // 替換 Route::match(...) 為 match(...)
'/Route::redirect\s*\(([^)]*)\)/', // 替換 Route::redirect(...) 為 redirect(...)
'/Route::view\s*\(([^)]*)\)/', // 替換 Route::view(...) 為 view(...)
'/Route::controller\s*\(([^)]*)\)/', // 替換 Route::controller(...) 為 controller(...)
'/Route::resource\s*\(([^)]*)\)/', // 替換 Route::resource(...) 為 resource(...)
'/Route::group\s*\(([^)]*)\)\s*{/', // 替換 Route::group(...) { 為 group(...) {
'/}\s*Route::[a-zA-Z]+\s*\(([^)]*)\)/', // 替換 } Route::...(...) 為 } ...(...)
// 可以根據(jù)需要添加其他的替換規(guī)則...
];
$replace = [
'$1', // 替換 Route::get(...) 為 get(...)
'$1', // 替換 Route::post(...) 為 post(...)
'$1', // 替換 Route::put(...) 為 put(...)
'$1', // 替換 Route::patch(...) 為 patch(...)
'$1', // 替換 Route::delete(...) 為 delete(...)
'$1', // 替換 Route::any(...) 為 any(...)
'$1', // 替換 Route::match(...) 為 match(...)
'$1', // 替換 Route::redirect(...) 為 redirect(...)
'$1', // 替換 Route::view(...) 為 view(...)
'$1', // 替換 Route::controller(...) 為 controller(...)
'$1', // 替換 Route::resource(...) 為 resource(...)
'$1 {', // 替換 Route::group(...) { 為 group(...) {
'} $1', // 替換 } Route::...(...) 為 } ...(...)
// 添加其他的替換結(jié)果...
];
$webmanCode = preg_replace($search, $replace, $code);
return $webmanCode;
}
/**
* getArr
* @author Bruce 2023/7/11
* @param $laravelCode
* @return array|string|string[]
*/
public function replaceLaravelController($laravelCode)
{
$webmanCode = str_replace('App\Http\Controllers', 'app\controller', $laravelCode);
$webmanCode = str_replace('use Request', 'use support\Request', $laravelCode);
return $webmanCode;
// 進行其他Controller轉(zhuǎn)換邏輯...
}
}
// 使用示例:
$converter = new LaravelToWebmanController('/path/to/laravel/project', '/path/to/webman/project');
$converter->convertControllers();
$converter->convertModels();
$converter->convertViews();
$converter->convertRoutes();
如果框架的輔助函數(shù)也用命名空間,可以直接合并起來用??刂破鬟@些遷移方便,但很多是用了框架自帶的功能,這些遷移起來就比較耗時了,特別是laravel自帶的功能實在很方便,但要遷移就坑了,雖然是組件,但是要遷移也夠嗆
雖然寫法上很類似了,但兩者進行轉(zhuǎn)換還是困難,比如校驗器、隊列、定時任務(wù)之類的適配起來還是很麻煩。
如果真正是為了方便應(yīng)用程序要適應(yīng)各個框架,應(yīng)用程序本身的設(shè)計可能更重要,也可以說會更為通用。本質(zhì)上就是讓應(yīng)用程序與框架解耦,可以參與DDD設(shè)計規(guī)范吧
沒有必要,在說很多人引用的包、編寫語法,業(yè)務(wù)設(shè)計出入是很大的,要兼容本身難度也大,二是沒必要遷移。laravel適合做中大形后端管理,webman的重點在小程序app這些高并發(fā),對于老項目沒有高并發(fā)需求,完全沒有必要遷,對于有高并發(fā)需求的,對高并發(fā)部分直接復(fù)制代碼出來基于webman重構(gòu)更好。新項目有高并發(fā)的可以完全webman
我的處理方式就是webman與laravel一起,共享數(shù)據(jù)庫與緩存及登陸認證共享,主要是緩存部分與token的加密碼方案要一至就行了,都用orm與cache 寫法完全一樣,僅須要高并發(fā)的用webman來運行,通過Nginx轉(zhuǎn)發(fā)用同一域名。
另外采用模塊化開發(fā),業(yè)務(wù)代碼中少引用獨立的包,是可以和webman共用一套代碼的,在webman的composer.json中把命名空間與路經(jīng)定義好,就可以在webman與laravel中同時運行,僅須要對webman的路由定義一條全局通用模塊路由即可,要性能走webman,不須要的情況下就直接laravel了
公司的項目不多,先是把tp工程一點一點改造成適合webman能運行的邏輯,即清除所有exit,die,盡量return,加入拋異常機制,改完之后,直接復(fù)制到app目錄就能跑了
wenman,laravel,thinkphp我的寫過,想要通過工具遷移代碼來遷移的前提就是本身項目代碼比較好,不然基本無法遷移
1,很多thinkphp5,6的項目,還會面向過程的方式寫的,第三方組件是自己吧包直接放在項目里,甚至不用composer來安裝包
2,laravel組件太多太多,幾乎無法做到遷移所有代碼
3,webman的代碼基本和laravel可以寫的幾乎一模一樣,所以規(guī)范代碼寫法才是關(guān)鍵,奢望吧亂七八糟的項目直接遷移過去基本不可能
4,采用 https://github.com/joanhey/AdapterMan 這樣可以,但還是比較建議的做法是先規(guī)范代碼,然后在去做遷移
我舉幾個代碼cms例子:
laravel cms https://gitee.com/open-php/zx-laravel-website
webman cms https://gitee.com/open-php/zx-webman-cms
hyperf cms https://gitee.com/open-php/zx-hyperf-cms
Goravel cms https://gitee.com/open-php/zx-goravel-cms
業(yè)務(wù)幾乎寫的一模一樣,想遷移就很簡單了,除非使用ai去做業(yè)務(wù)代碼轉(zhuǎn)譯,不然真的不太可能