Tencent / Biny

Biny is a tiny, high-performance PHP framework for web applications
BSD 3-Clause "New" or "Revised" License
1.69k stars 259 forks source link

mysql 位查询可以支持么 #94

Closed itbirds closed 5 years ago

itbirds commented 5 years ago

在实际业务中经常会使用一个字段表示多个值,同时多个值是可以组合的,这种情况可以使用多个逗号隔开,然而这样扩展比较麻烦,使用二进制的方式可以很好避免这个问题,但是biny框架好像不支持位查询,在文档中也未找到相关说明

billge1205 commented 5 years ago

目前的确没支持位运算,但还是可以通过sql模板的方式实现,例如: $this->userDAO->filter(['type'=>1])->select('SELECT status & 4 FROM :table WHERE :where and status & 1'); 我考虑下非模板形式下的位运算支持,主要在于定义方便好用的数据结构,如果有好的建议,也欢迎PR

itbirds commented 5 years ago

你好,我自己修改了buildWhere方法,改的不好,我的思路是类似<或>那种方式,但是&符号可能会有专一的麻烦,可以使用特定字符串代替,在buildWhere里面加上判断。我自己觉得这样方式不是很好,改动了框架。

同时我之前发现一个情况,不知道是不是我使用不对,情况如下:

`

public function action_index(){
$model1 = \App::$model->filmModel;
$model2 = \App::$model->categoryModel;
var_dump(get_class($model1));
var_dump(get_class($model2));
exit;
}`

输出结果如下: string(19) "app\model\filmModel" string(19) "app\model\filmModel"

billge1205 commented 5 years ago

我这边在考虑用一种特殊的object类型来实现,例如: $bit = Database::bit(4, '&'); $this->userDAO->filter(['status'=>$bit])->query(); 下面那个问题我这边没有复现出问题,不知道跟你这边定义的model文件类名什么的是不是有关系 或者你看下 categoryModel init方法返回的对象是不是返回了filmModel类

billge1205 commented 5 years ago

如果只是要where中条件判断的话 现在已经更新支持了 参考了你的建议 $this->userDAO->filter(['&'=>['status'=>4]])->filter(['>>'=>['type'=>2]])->query(); 同时也支持了位移判断

itbirds commented 5 years ago

首先谢谢作者及时回复和修复跟进。

关于二种实现方式,我认为object和where条件判断都行,看哪种对框架封装性破坏更小就行。

第二问题,我打印了init也是一样的,

控制器里面

public function action_index(){
    $model1 = \App::$model->filmModel;
    $model2 = \App::$model->categoryModel;

    var_dump(get_class($model1));
    var_dump(get_class($model2));

    var_dump($model1->init());
    var_dump($model2->init());
    exit; }

baseModel.php

public static function init($id=null) { var_dump($id); if (!isset(static::$_instance[$id])){ static::$_instance[$id] = new static($id); } return static::$_instance[$id]; }

输入内容: NULL NULL string(19) "app\model\filmModel" string(19) "app\model\filmModel" object(app\model\filmModel)#12 (7) object(app\model\filmModel)#12 (7)

我理解的这里执行的过程如下: 调用Model::create()方法去实例化对应model类文件,这里用call_user_func_array,实例化同时去调用init方法,我在二个子类里面都没有实现init方法,因此这里调用到baseModel下的init方法,同时parms作为参数传入方法,因为我上面调用params变量都是空的,因此在baseModel里面的id都是null,这样取的都是一个model对象。不知道我说的是否清楚表述清楚了

billge1205 commented 5 years ago

baseModel里的init 是static::$_instance子类的单例集对象,理论上不应该会命中同一个单例集。可能跟你的PHP版本有关。 你可以把baseModel中的init方法删除,框架里默认找不到init方法 会new实例化该对象

itbirds commented 5 years ago

谢谢,我看了一下例子里面的person.php这个model,里面有init实现,同时对id做了判断。应该是我使用的问题,

itbirds commented 5 years ago

感谢作者,关于MySQL的位查询,我看作者已经更新了,第二个问题应该是我使用不对,在model子类参照作者例子需要实现init方法及id判断

billge1205 commented 5 years ago

框架里baseModel中的init方法已删除(其实没必要存在,会引起干扰) App::$model->filmModel(xxx) 调用时 如果filmModel对象有init方法 会调用 filmModel::init(xxx) 如果不存在init 方法,会返回 new filmModel(xxx) 有问题欢迎讨论~