REPL for php ,在yii中使用 REPL

PHP · yiqing · 于 2年前 发布 · 2710 次阅读

php中也是近几年才有的REPL功能!前几年难道一直没有实现么!

REPL 是一个缩写 代表(READ EVAL PRINT LOOP),是比较标准的命令行交互模式。

   读入用户的输入  执行代码  打印结果  只要用户不退出就一直循环这个过程。
        R              E        P                 L

脚本类语言基本都有这样的实现。

缘起

最近在看python的一个flask框架(就是瞎看 不要有心理压力哦)。 这个框架其实跟yii也很像 至少使用经历上来说没有太大跨度(web类框架估计就那几种常见 的风格 用什么语言无所谓 底层思想都互抄!)

也是 建模型 -》 用migration 建表 --》然后建UI (他们也有一个表单类wtform类 功能地位等价 yii中的XxxForm 属于Model的子类 专门跟表单交互的 不过他们的视图层没有ActiveForm 这样强大的东西 需要手动敲原始的html 表单构造 wtform主要用来定义字段类型跟完成验证功能)


    import wtforms
    from wtforms import validators
    from models import User
         class LoginForm(wtforms.Form):
         email = wtforms.StringField("Email",
         validators=[validators.DataRequired()])
         password = wtforms.PasswordField("Password",
         validators=[validators.DataRequired()])
         remember_me = wtforms.BooleanField("Remember me?",
          default=True)

跑题了 说的不是这个:)

开发流程也是表驱动 先建立表 然后建立模型 然后在模型上实现业务方法(静态或者实例化 方法) , 在这一步的时候 需要验证一下业务方法是否实现正确。

此时 python用REPL 可以简单的验证逻辑是否实现正确。很是方便。 但这种功能要在php中 就有点麻烦了 要验证功能 你必须调用它 ,此时 要么你写一个视图 --》控制器 --》 action 这个流程来触发业务层的代码。 要么 从控制台程序中调用。 或者你自己写phpunit 等测试也可以。 但这些都嫌麻烦 不及REPL 直接插入业务逻辑层之上 随意调用业务层的接口。

现代php框架基本都是层模式(MVC是层模式的一种),开发流程无外乎 从底层向上 或者从 UI层往内(这种是用例驱动的 从边界类 到控制类 再到实体类),也有乱来的时而从上往下 时而从下往上。:d:

在层模式中 当你从外层往里侧开发时 为了验证功能 往往使用的是mock假对象 假数据,先 临时满足当前层的功能 所依赖的底层给你“喂“一些假数据(此时php中的faker库 就很有用了)

当你从底层db 往上开发时(yii 就这种风格),如果想验证下层某个功能api是否如预期那样 必须使用单元测试 或者临时写一个 控制器|action 来调用这个业务逻辑 。单元测试比较麻烦 写这些临时控制器,也感觉比较“脏” 会污染系统的纯洁性的 。此时就迫切需要一种随用随 消失的功能。OK 终于迁到正题了 该猪脚登场了“REPL”

php中的ERPL==> PsySH 使用composer 全局安装一下 你就可以开始使用了!


    composer g require psy/psysh:@stable
    ...
    
    - Installing psy/psysh (v0.1.11)
    Downloading: 100%
    
    ...
    
    
    C:\Users\Lenovo\Documents>psysh
    Psy Shell v0.1.11 (PHP 5.6.3 鈥?cli) by Justin Hileman
    >>> echo "hello";
    hello鈴?
    => null
    >>> 1+2
    => 3
    >>>

吼吼是不是很帅 ! 当然 你可以在你项目目录下启动这个psysh 因为你毕竟是想借助它 来和你项目中的类 或者脚本来交互的:


    D:\Visual-AMP-x64\www\yii2-space\yii_blog>psysh
    Psy Shell v0.1.11 (PHP 5.6.3 鈥?cli) by Justin Hileman
    >>> require('config/params.php');
    => [
           "adminEmail" => "admin@example.com",
           "uploadsDir" => "@webroot/uploads"
       ]
    >>>

比如我上面就是在yii的一个项目中启动psysh命令 这样我可以根据当前目录 来做一些操作 。

psysh很是强大 可以前往官网 仔细阅读其能干啥哦。

跟YII的集成

yii官方扩展库中实际集成了它 ! 就是yii2-shell

看到它的代码很少,实际就是简单的对psysh做了个适配 搭个桥而已。底层还是使用人家 的功能。

但即便这样 这个桥也可以把psysh带人到当前yii的世界,因为是借助yii的console程序进入 的,所以为你带来的可访问东西 就是你在某个console的某个控制器下能访问的东西。


    D:\Visual-AMP-x64\www\yii2-space\yii_blog>yii shell
Psy Shell v0.7.2 (PHP 5.6.3 鈥?cli) by Justin Hileman                                                                                                                                                              
>>> my\user\models\User::create('yiqing_95@qq.com','yii2coder',['username'=>'yiqing'])
=> my\user\models\User {#183
     +currentPassword: null,
     +newPassword: null,
     +newPasswordConfirm: null,
     +module: amnah\yii2\user\Module {#188
       +alias: "@user",
       +requireEmail: true,
       +requireUsername: false,
       +useEmail: true,
       +useUsername: true,
       +loginEmail: true,
       +loginUsername: true,
       +loginDuration: 2592000,
       +loginRedirect: null,

我该方法的代码是(位于User 类中):

   
     /**
     * |+  ------------------------------------------------------------------------------   +
     */

    /**
     * @param string $email
     * @param string $password
     * @param array $attributes
     * @return static
     * @throws \yii\base\Exception
     */
    public static function create($email, $password, $attributes = [])
    {
        $model = new static();
        $model->email = $email;
        // 自动做加密
        $model->password = Yii::$app->security->generatePasswordHash($password);

        $model->setAttributes($attributes);

        return $model;

    }

    /**
     * @param string $email
     * @param string $passord
     * @return array|bool|null|ActiveRecord
     */
    public static function authenticate($email = '', $passord = '')
    {
        $user = static::find()->where([
            'email'=>$email,
        ])->one() ;
        if($user->validatePassword($passord)){
            return $user ;
        }

        return false ;
    }

    /**
     * +  ------------------------------------------------------------------------------   +|
     */

可以看到 直接可以跟模型层交互 ,通过psysh 直接就插入到 控制器层 和模型层中间了。

当然 yii shell 这个命令 是需要你安装扩展的 就是yii2-shell 用composer 安装后就可以玩耍了!


        
    D:\Visual-AMP-x64\www\yii2-space\yii_blog>yii shell
    Psy Shell v0.7.2 (PHP 5.6.3 鈥?cli) by Justin Hileman
    >>>
    >>> my\user\models\User::authenticate('yiqing_95@qq.com','yiqing')
    => my\user\models\User {#186
         +currentPassword: null,
         +newPassword: null,
         +newPasswordConfirm: null,
         +module: amnah\yii2\user\Module {#192
           +alias: "@user",
           +requireEmail: true,
           ...
       }
    >>> my\user\models\User::authenticate('yiqing_95@qq.com','wrong password')
    => false
    

看到我上面两个业务方法直接可以使用yii2-shell 方便验证,太帅了!!

建议大家下下来用用 ,这个扩展 好像被很多人冷落 估计都是不知道咋玩耍吧。

本文由 yiqing 创作,采用 知识共享署名 3.0 中国大陆许可协议 进行许可。 可自由转载、引用,但需署名作者且注明文章出处。

本帖已被设为精华帖!
共收到 6 条回复 Yii 扩展 REPL Test
forecho#12年前 0 个赞

:plus1: 酷

fecommerce#22年前 0 个赞

能说一下具体的用处吗、?命令行和 传统的方式? 给予更多的调试信息? 用trace追踪能显示更详细的log

forecho#32年前 0 个赞

@fecommerce #2楼 我觉得是可以更方便的是快速验证你的代码

fecommerce#42年前 0 个赞

@forecho #3楼 恩,验证配置后,yii2各个组件的参数设置。

yiqing#52年前 0 个赞

@fecommerce #2楼 REPL 这个你需要搜索下 先看看这个干啥用的 抛开yii不说 你可以使用psysh 直接做其他交互式shell可以做的事 你用进程思想来思考 如果你做了一个web页 然后在上面敲php代码 然后代码以字符串的形式传递给 psysh进程 这个进程可以执行你的代码 执行完后 在返回给web服务器 然后返回结果给浏览器 这样几乎可以实现一个在线php交互编程功能 我只是这样想 具体能否实现还不清楚

实际上你用了 yii-shell 可以在命令行中 访问你模块中的某个功能 不需要从控制器的action进入 yii中 进入系统功能的方法 常规就是需要你写某个控制器的某个action 然后在action中 访问功能 但你必须建立文件 这样有时候很麻烦 等你文件类什么的都建立好了 可能就忘了你要干啥 这时直接打开 yii-shell 立即就可以调用你的 方法 验证正误 当然你也可以写单元测试 来验证你的功能 这个体验是很像的

fecommerce#62年前 0 个赞

@yiqing #5楼 恩,多谢!

添加回复 (需要登录)
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册