有没有考虑写一个工具,方便迁移laravel和thinkphp项目代码到webman的

zhezhebie

项目迁移

现在laravel和thinkphp还有webman,其实区别不是特别大了,能不能写一个迁移工具,方便迁移这两个项目代码到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转换完成!';
    }

    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转换完成!';
    }

    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转换完成!';
    }

    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 '路由转换完成!';
    }

    private function convertLaravelToWebman($laravelCode, $type)
    {
        // 在这里实现将Laravel代码转换为Webman代码的逻辑
        // 这个函数应该根据Laravel和Webman的不同结构进行相应的转换
        // 请根据实际情况自行编写
        // 这里只是一个示例,可能并不适用于你的项目

        if ($type === 'controller') {
            $webmanCode = $this->replaceLaravelController($laravelCode);
        } elseif ($type === 'model') {
            // 进行Model转换逻辑...
            $webmanCode = $this->replaceLaravelModel($laravelCode);
        } elseif ($type === 'view') {
            // 进行View转换逻辑...
            $webmanCode = $this->replaceLaravelBladeSyntax($laravelCode);
        } elseif ($type === 'route') {
            // 进行Route转换逻辑...
            $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);

        // 进行其他模型转换逻辑...
        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;
            // 可以根据需要添加其他的替换规则...
        ];

        $replace = [
            '<?php echo $1; ?>',
            '<?php echo $1; ?>',
            '<?php if ($1): ?>',
            '<?php elseif ($1): ?>',
            '<?php else: ?>',
            '<?php endif; ?>',
            // 添加其他的替换结果...
        ];

        $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::...(...) 为 } ...(...)
            // 可以根据需要添加其他的替换规则...
        ];

        $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::...(...) 为 } ...(...)
            // 添加其他的替换结果...
        ];

        $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转换逻辑...
    }
}

// 使用示例:
$converter = new LaravelToWebmanController('/path/to/laravel/project', '/path/to/webman/project');
$converter->convertControllers();
$converter->convertModels();
$converter->convertViews();
$converter->convertRoutes();
5100 15 2
15个回答

walkor 打赏

这个想法很好,有想过做个迁移工具,但是我实在对这两个框架不熟。
谁搞一个可以放到插件市场获取收益,或者做成服务收费都行

  • zhezhebie 2024-01-08

    如果有这个工具,我觉得会让webman的使用率增大好几倍,laravel性能太差了

  • zhezhebie 2024-01-08

    能不能把这个贴子置顶,看看有没有人感兴趣,一起讨论下怎么做,然后一起开发下,这两个框架挺像的。

  • tyt 2024-01-08

    fastadmin哪这里的应用 就可以 全部转换过来了。

  • ab0029 2024-01-09

    大佬webman有没打算把helper.php出个带命名空间的版本,这样其实也不需要迁移了,直接把框架冲突都解决了,虽然这个也不太实际,比较和前面版本的变动不兼容了。

JaguarJack

这个需求量大吗?开发工作量应该不小的,有需求在下面集合下😂

  • 暂无评论
ab0029

如果框架的辅助函数也用命名空间,可以直接合并起来用。控制器这些迁移方便,但很多是用了框架自带的功能,这些迁移起来就比较耗时了,特别是laravel自带的功能实在很方便,但要迁移就坑了,虽然是组件,但是要迁移也够呛

  • 暂无评论
gddd

完全没有意义,真正的项目不会需要这东西,用的都可能都是个人项目

  • 暂无评论
wocall

小白来了,这两个都没用过

  • 暂无评论
JaguarJack

还没试过 webman,Laravel 里面有大量的服务。webman 如何实现呢

  • 暂无评论
caylof

虽然写法上很类似了,但两者进行转换还是困难,比如校验器、队列、定时任务之类的适配起来还是很麻烦。

如果真正是为了方便应用程序要适应各个框架,应用程序本身的设计可能更重要,也可以说会更为通用。本质上就是让应用程序与框架解耦,可以参与DDD设计规范吧

  • 暂无评论
tangniyuqi

Yii2 虽然也可以 但更新有点慢 也可以迁移了

  • fklee 2024-01-10

    YII2的数据库操作类能迁移到webman吗,还是YII的用起来舒服

  • tangniyuqi 2024-01-10

    对 我也觉得

  • ak47f16200 2024-01-19

    一直在找,社区好像有人搞了,但好像一直 没放出来

  • fklee 2024-01-19

    有人能分享出来就好了,奈何自己能力不够,不然新项目全上webman

  • nilyang 2024-03-01

    我也觉得,Yii好舒服,但缺workerman整合

xini2603

没有必要,在说很多人引用的包、编写语法,业务设计出入是很大的,要兼容本身难度也大,二是没必要迁移。laravel适合做中大形后端管理,webman的重点在小程序app这些高并发,对于老项目没有高并发需求,完全没有必要迁,对于有高并发需求的,对高并发部分直接复制代码出来基于webman重构更好。新项目有高并发的可以完全webman

我的处理方式就是webman与laravel一起,共享数据库与缓存及登陆认证共享,主要是缓存部分与token的加密码方案要一至就行了,都用orm与cache 写法完全一样,仅须要高并发的用webman来运行,通过Nginx转发用同一域名。
另外采用模块化开发,业务代码中少引用独立的包,是可以和webman共用一套代码的,在webman的composer.json中把命名空间与路经定义好,就可以在webman与laravel中同时运行,仅须要对webman的路由定义一条全局通用模块路由即可,要性能走webman,不须要的情况下就直接laravel了

hongshao

公司的项目不多,先是把tp工程一点一点改造成适合webman能运行的逻辑,即清除所有exit,die,尽量return,加入抛异常机制,改完之后,直接复制到app目录就能跑了

  • 暂无评论
shiyun

留个脚印,正在实现

  • zhezhebie 2024-02-02

    来来来,一起搞,贴个仓库地址

ben
zh7314

wenman,laravel,thinkphp我的写过,想要通过工具迁移代码来迁移的前提就是本身项目代码比较好,不然基本无法迁移
1,很多thinkphp5,6的项目,还会面向过程的方式写的,第三方组件是自己吧包直接放在项目里,甚至不用composer来安装包
2,laravel组件太多太多,几乎无法做到迁移所有代码
3,webman的代码基本和laravel可以写的几乎一模一样,所以规范代码写法才是关键,奢望吧乱七八糟的项目直接迁移过去基本不可能
4,采用 https://github.com/joanhey/AdapterMan 这样可以,但还是比较建议的做法是先规范代码,然后在去做迁移

我举几个代码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

业务几乎写的一模一样,想迁移就很简单了,除非使用ai去做业务代码转译,不然真的不太可能

  • 暂无评论
wanganlin

一款基于 Workerman 的高性能 PHP HTTP 服务框架。
https://github.com/colaphp/colaphp

  • wocall 2024-07-11

    你不好好做个介绍么?看了官网,除了安装外,没看到能干啥用啊

zjkal✅

thinkphp迁移过来应该比较容易, laravel难度就比较大了

  • 暂无评论
×
🔝