打通 Laravel 和 Yii2 任督二脉

阅读 962
收藏 15
2017-05-25
原文链接:segmentfault.com

Yii2与Laravel相爱相杀已经很久了,导致广大PHP爱好者必须选边站队,生怕自己站错了阵营。作为一个已经上了Yii2贼船很久的人想换船是需要很大勇气的,能不能就在现有框架基础上尝尝Laravel的鲜,同时万一不合适还能及时回头是岸呢?无论如何我也要趟一趟这趟浑水,看看人们传说已久慕名已久的Laravel到底有多好,是不是真的比Yii2要好很多?

安装Laravel

安装过程很简单,照着说明书一步一步操作,只要执行

laravel new project_name

就很快建立了你的第一个Laravel项目。配好Apache,打开浏览器,你已经能看到第一个页面。作为职业PHP选手,第一件事情就是要看看这个页面是从哪里来的,答案很明显,就在/resources/views/welcome.blade.php当中,先不要管它这个blade是个什么鬼,其中的一段话吸引了我:

        @if (Route::has('login'))
            <div class="top-right links">
                @if (Auth::check())
                    <a href="{{ url('/home') }}">Home</a>
                @else
                    <a href="{{ url('/login') }}">Login</a>
                    <a href="{{ url('/register') }}">Register</a>
                @endif
            </div>
        @endif

看来它是自带有登录注册系统的,但是我没有看到这个登录注册按钮。于是直接暴力开干,找说明书查询。书上有讲:

php artisan make:auth

终于看到了登录注册按钮。但是这时候肯定是连不通的,想也知道,我们还没有配数据库嘛。测试登录,果然不通。

一般情况下,这时候应该遵照官方手册,开始建立Laravel自己相配套的数据库体系。但是,我们偏偏不要遵循官方教程,因为我们自己已经有了我们已经有Yii2做好的数据库,为什么要另起炉灶呢?我们偏偏就要让Laravel使用Yii2建好的数据库,否则我那么多用户数据怎么办?就算我把Yii生成的user表里的数据导入Laravel自己建的数据库,那我将来想两边都共用怎么办?所以必须强制它们住在一个屋檐下!

配置Laravel数据库

查看Laravel代码,/config/database.php,其中有如下配置:

'mysql' => [
    'driver' => 'mysql',
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'unix_socket' => env('DB_SOCKET', ''),
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix' => '',
    'strict' => true,
    'engine' => null,
],

但是直接更改这里是行不通的,很聪明,这跟我们Yii2里的config/main.php是异曲同工之妙,Laravel把与环境相关的数据库配置放在了/.env文件里,而.env文件是被.gitignore了的,完全等价于Yii2的config/main-local.php。明白了这个就好办了,修改/.env文件:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=mydatabase
DB_USERNAME=root
DB_PASSWORD=

刷新页面,重新登录。数据库是连通了,出现了熟悉的错误:找不到users表。

让Laravel使用Yii2的数据库表

这是因为Yii2自己建立的用户表名字叫user,而Laravel想找的表是users,差一个字母。那我们是不是要把表名改成users或者再给它新建一个users表呢?No, no, no。那样就失去了我们今天课程的精髓,我们偏偏就要让Laravel来使用Yii2的user表。

Laravel是把自己的model文件保存在app目录下的,我们在这个目录里可以找到一个文件叫做:/app/User.php。在这个文件里,我们来给它进行一点小小的改造,加上这么一行:

protected $table = "user";

我想你应该明白这是什么意思。于是乎,Laravel不再试图去从它想找的users表里找用户,而改从我们告诉它的user表里找用户。但是,不要高兴得太早,你依然是登录不进去的,因为表虽然对了,但是列不一定对,因为我们的Yii2是把密码哈希值存储在password_hash列里,而Laravel缺省要找的是password列,所以我们还要通过User.php文件告诉Laravel请你从password_hash列里找密码:

public function getAuthPassword()
{
    return $this->password_hash;
}

不止如此,Laravel选择当用户记住密码时保存token的列叫作remember_token,而Yii2叫作auth_key,这两者也不一样,于是你还需要再加上:

public function getRememberTokenName()
{
    return 'auth_key';
}

再试一下,你已经可以用你旧的Yii2用户的密码登录Laravel系统了!

无法登出

问题总是一个接着一个,虽然可以登录了,但是还是无法登出,登出会报一个错误,原因是因为上面那一列auth_key,Yii2在建表的时候,缺省给的是一个32位长的字符串,而Laravel需要更长。所以我们多少还是需要小动一下我们的数据库结构,鉴于此,我们通过Yii2的migration来管理我们所有数据库的修改:

./yii migrate create alter_user_authkey_column

Yii2系统会帮我们在/console/migrations下自动生成一个文件,我们只需要简单修改一下就好了:

use yii\db\Schema;
use yii\db\Migration;

class m170523_060237_alter_auth_key_column_from_user_table extends Migration
{
    public function safeUp()
    {
        $this->alterColumn('user', 'auth_key', Schema::TYPE_STRING . '(100) NOT NULL');
    }

    public function safeDown()
    {
        $this->alterColumn('user', 'auth_key', Schema::TYPE_STRING . '(32) NOT NULL');

        return false;
    }
}

safeUp是指向上升级的时候要做的动作,safeDown是指万一失败了回退时的动作。

因为我们数据库中已经有user表了,所以我们不能再执行对于user表的migration动作,所以需要先告诉Yii2我们已经执行过user表的migration了,不要再执行:

./yii migrate/mark 130524_201442

好了,现在再执行./yii migrate就可以看到你想要的结果了。

登入登出完全正常,Laravel终于可以和Yii2和和美美地住在一个小房子里了。

评论