目錄
回复讨论(解决方案)
首頁 後端開發 php教程 WEB编程架构改革初探

WEB编程架构改革初探

Jun 23, 2016 pm 01:39 PM


长久以来,编程MVC架构深入人心。随着编程语言的不断进步和发展。这种架构始终没有进步, 我们尝试着将MVC模式大胆进化为VC模式。【千万注意】,我用的是进化,是先有MVC,再有VC。而不是直接VC模式。

再次强调,不是说MVC模式不好。其实还可以进化得更好。当MVC模式你还不熟悉的时候,你无法理解VC模式。
表面上省略掉Model,是编程语言进化的结果。而不是退步。为此会带来效率的大幅度提升。。。

一、 省略掉model的前提条件。
二、 省略掉model的实现。
三、 省略掉model后的强大好处。
四、 如何弥补省略掉model所失去的功能?
五、 为此VC架构的php框架实现。
以上功能下面慢慢补充…
在此抛砖引玉,希望大家不吝赐教。。。。
跟贴有分啊。。。。


回复讨论(解决方案)

先丢块砖:你这是退化到 MV

先丢块砖:你这是退化到 MV



【千万注意】,我用的是进化,是先有MVC,再有VC。而不是直接VC模式。


先丢块砖:你这是退化到 MV



【千万注意】,我用的是进化,是先有MVC,再有VC。而不是直接VC模式。 '
只是说了总纲,具体怎么做呢?

WEB编程架构改革初探

长久以来,编程MVC架构深入人心。随着编程语言的不断进步和发展。这种架构始终没有进步, 我们尝试着将MVC模式大胆进化为VC模式。【千万注意】,我用的是进化,是先有MVC,再有VC。而不是直接VC模式。

再次强调,不是说MVC模式不好。其实还可以进化得更好。当MVC模式你还不熟悉的时候,你无法理解VC模式。
表面上省略掉Model,是编程语言进化的结果。而不是退步。为此会带来效率的大幅度提升。

一、 省略掉model的前提条件。
1) 你必须要知道什么是Model。Model就是数据库操作层,负责与数据库打交道的相关操作。(在此省略很细的DB驱动层),将常用的数据库操作方法对象化。在Controler层可以不用直接操作数据库,将业务逻辑和数据处理分离。有利于程序扩展和维护。
2) 既然model层如此重要,为何要省略,不是这些好处全部没有了吗?
二、 省略掉model的实现。
1) 先说Model层的坏处:在MVC模式下,各种类之间的调用过于复杂,文件加载过于频繁,这就是php框架中MVC模式的带来的负作用,速度太慢了。像Java一样,大炮打蚊子,任何一个小动作,都扯了太多的类进来:这就导致2个问题,一是调用太多类已经由量变到质变。框架程序变得非常复杂:比如TP3.2。二是加载过多类,程序速度开始变得非常慢。程序速度瓶颈已经由DB转化为框架了。
2) 哪我们有木有一种方案,即能享受M层带来的便利,又能避免M层所带来的坏处呢?经过一段时间研究,我发现有一个这样方法。就是类似TP中的model层。将数据库操作,完全方法化。使用者在完全不用写任何SQL语句的情况下可以操作数据库。当然TP中很多Model方法还不够简单和傻瓜化。比如Join方法。还有封装的余地。
       
三、 具体实现:
1) DB类->Controller基类。
2) DB类当然就是封装数据库操作了。Controller调用DB类。来实现客户端需要方便操作DB的所有方法。比如where,orderby.count,join,joinUser,joinOwer等。
3) 用户UserControler直接继承基类Controler.数据库操作直接通过基类Controler实现。而UserControler 只顾管好自己的业务逻辑就好。
4) Model的功能,实际由基类Controler透明化,省略化了。因为基类Controle太强大。
四、 省略掉model后的强大好处。
1) 首先是层次简单,调用类减少,程序简单,速度增加,但model层提供的功能一点都没有减少,反而有增加。
2) 由于Controler层和Model层合二为一,带来的好处就是。Controler可以分步,直接操作数据库。在分步中间,就可以编写插件。而且插件可以集成在基类Controler中,或者继承于Controler后的子类。供其它子类调用。
3) 例子:分页和搜索插件:前台和后台几乎不用写一行代码(复制几行安装代码而已),就可以实现极为强大而又复杂的非常专业的搜索和分页功能。应用于任何WEB页。就是在省略model层下实现的。如果不是二者合为一。根本没有办法实现此插件。
4) 关于速度。由于连接数据库,全部采用Lazy需要时连接,和常用数据缓存功能,程序性没有一丝浪费。
五、 如何弥补省略掉model所失去的功能?
其实:有时候,有些功能,即不是业务逻辑,又不是数据处理。这时候,我们可以将此功能封装后,类库化,需要时调用。

六、 为此VC架构的php框架实现。
1、 控制器基类:调用DB(mysqlDB)类。通过方法实现客户端调用时不用任何SQL语句,就可以方便操作数据库。
2、    View类。实现模板标签解析。
3、 单入口index.php.实现框架控制器VC功能。
七、 实践:通过3天时间,完全实现第六步所讲的框架功能。正在应用此框架开发公司实际项目编程半月以上(团队几人在应用此框架编程)。结果:
1) 学习成本在20分钟左右,最多不超过1个小时。
2) 编程实现和TP3.2功能几乎一样,不过更代码简单(编写,维护,阅读)。
3) 继承类Controler中,大部分方法业务逻辑部分代码就几行。超过20行的非常少。由此可见,省略掉model层,根本没有增加controler层代码量。
4) 同样的程序速度相比TP3.2提升5倍以上性能。

在此抛砖引玉,希望高手不吝赐教。本人写此文的目的,就是希望有高手能指出其中的不足,而不是泛泛的说别人不懂程序。或者说是一种退步。本人各种编程语言经验几十万行。从业10来年,还在不断探索之中。
PHP高手交流千人qq群:317172514.想和作者交流,请加入此群共同探讨WEB编程。

还有这样进化的哇,占个座看楼主继续发表观点。

MVC中M的主要是处理数据库或者业务逻辑。
更简单的说,其实把C看成商人,V看成顾客,而M则看成生产商。当生产商(M)取消后,那么意味着商人(C)就要承担生产商(M)的责任。虽然看似省略了一步,但其实只是内部消化而已,没了M,那么必然会有另一种产物来替代,来解决所有只在C中处理的业务。当然,也可以都用C,不用M或另一种替代M的方案,这也会使C的负担增大,代码也会更加复杂,代码重用性也会相对降低等等。Thinkphp中封装的一些数据库操作的方法,但未必就不是M的代替口。

个人观点,不喜勿喷~~~

Model就是数据库操作层???
这个观点太狭窄了,Model是业务逻辑,当然也包括数据库操作
由于你在使用 TP,所以你就被他替你完成(示例)的部分所迷惑了
其实 TP 有一套完整的 Model 调度方案。之所以拿数据库访问做示范,是因为他不可能知道你的业务逻辑是什么,而透过 DESCRIBE 指令可以方便的构造出供演示的类。并且由于有具体的数据,可以直观的描述他的使用方法。但绝不是全部
C 本来是 M 和 V 之间的桥梁,但由于 MVC 间没有明确的分工,所以很多情况下就把本属于 M 的代码放到了 C 里
你不过是想把整个 M 都放到 C 中,就是你所谓的 VC
但是无论如何,业务逻辑都是第一位的,所以 M、C 的混合体应该称为 M

楼主只考虑数据库,如果是非数据库的业务逻辑操作,这个MODEL要放在那里?

既然楼主已经有这样的一个框架,那就共享出来大家学习一下吧。

MVC中M的主要是处理数据库或者业务逻辑。
更简单的说,其实把C看成商人,V看成顾客,而M则看成生产商。当生产商(M)取消后,那么意味着商人(C)就要承担生产商(M)的责任。虽然看似省略了一步,但其实只是内部消化而已,没了M,那么必然会有另一种产物来替代,来解决所有只在C中处理的业务。当然,也可以都用C,不用M或另一种替代M的方案,这也会使C的负担增大,代码也会更加复杂,代码重用性也会相对降低等等。Thinkphp中封装的一些数据库操作的方法,但未必就不是M的代替口。

个人观点,不喜勿喷~~~



你这是过去的理论,没错,现在编程语言进化,比如php。省略model层。根本没有增加C的负担,反而减小了。这是实际编程出来的结果。

下面代码就是Controler中增加和显示客服的完整代码
public function add_kefu()	{	    if(isset($_POST['id']))	    {                $data['company_id']=$_POST['id'];                $data['kefu_name']=$_POST['kefu_name'];                $data['passwd']=$_POST['passwd'];                $data['kefu_type']=$_POST['kefu_type'];                $data['kefu_name']=$_POST['kefu_name'];                $data['open_time']=time();                if($data['kefu_type']=='robot')                    $data['is_online']=1;                $id=$this->table('kefu')->insert($data);                if($id)                {                    logs('(sql:):'.$this->getLastSql());                    alert('增加客服成功:其ID为:'.$id);                }else                {                    alert('增加客户失败:原因为:'.$this->getLastError());                }	    }else	    {	       $this->company_id=isset($_GET['id'])?$_GET['id']:0;	       $this->display();	    }	}
登入後複製
登入後複製
登入後複製


实际代码之二:

//查看本公司所有客服列表	public function view_kefu()	{	    $company_id=$_GET['id'];	    $list=$this->table('kefu')->where('company_id',$company_id)->select();	    if(is_array($list))	    formatDate($list, 'open_time,last_heartbeat');	    $this->assign('list',$list);	    $this->display();	}
登入後複製
登入後複製
登入後複製

这是真实代码之二。可以看出,都是非常简单的代码。

既然楼主已经有这样的一个框架,那就共享出来大家学习一下吧。



正在自己公司实践,写出来还没有一个月。

楼主只考虑数据库,如果是非数据库的业务逻辑操作,这个MODEL要放在那里?


与model无关,该放哪放哪。
其实这个问题,我上面早就回答了,做成类库调用。


MVC中M的主要是处理数据库或者业务逻辑。
更简单的说,其实把C看成商人,V看成顾客,而M则看成生产商。当生产商(M)取消后,那么意味着商人(C)就要承担生产商(M)的责任。虽然看似省略了一步,但其实只是内部消化而已,没了M,那么必然会有另一种产物来替代,来解决所有只在C中处理的业务。当然,也可以都用C,不用M或另一种替代M的方案,这也会使C的负担增大,代码也会更加复杂,代码重用性也会相对降低等等。Thinkphp中封装的一些数据库操作的方法,但未必就不是M的代替口。

个人观点,不喜勿喷~~~



你这是过去的理论,没错,现在编程语言进化,比如php。省略model层。根本没有增加C的负担,反而减小了。这是实际编程出来的结果。

下面代码就是Controler中增加和显示客服的完整代码
public function add_kefu()	{	    if(isset($_POST['id']))	    {                $data['company_id']=$_POST['id'];                $data['kefu_name']=$_POST['kefu_name'];                $data['passwd']=$_POST['passwd'];                $data['kefu_type']=$_POST['kefu_type'];                $data['kefu_name']=$_POST['kefu_name'];                $data['open_time']=time();                if($data['kefu_type']=='robot')                    $data['is_online']=1;                $id=$this->table('kefu')->insert($data);                if($id)                {                    logs('(sql:):'.$this->getLastSql());                    alert('增加客服成功:其ID为:'.$id);                }else                {                    alert('增加客户失败:原因为:'.$this->getLastError());                }	    }else	    {	       $this->company_id=isset($_GET['id'])?$_GET['id']:0;	       $this->display();	    }	}
登入後複製
登入後複製
登入後複製


实际代码之二:

//查看本公司所有客服列表	public function view_kefu()	{	    $company_id=$_GET['id'];	    $list=$this->table('kefu')->where('company_id',$company_id)->select();	    if(is_array($list))	    formatDate($list, 'open_time,last_heartbeat');	    $this->assign('list',$list);	    $this->display();	}
登入後複製
登入後複製
登入後複製

这是真实代码之二。可以看出,都是非常简单的代码。


这些代码确实简单,同时业务也不复杂~~
复杂的业务或需要复杂的sql,又该如何呢?
诚然,你上面的代码干净、利落,但是Think中用的M(),你这里用的this,或许是在C中封装的,但未必不是M的衍生物来代替Model的,复杂的东西依旧需要放到类库里或其他封装类里,也依旧是需要引用的

虽然观点不一致,但还是很佩服楼主的,有自己的想法和坚持~

楼主的那两段代码实际都是业务逻辑,属于M的范畴
作为实际的项目,当然可以这样写
但如果是继承于 model 的话,也就 D('add_kefu')、D('view_kefu') 这样就可以了
框架与实际项目的区别在于框架总是要与未知的对象打交道,所以任何一个环节都不能写死
实际项目只关心具体的业务,但写死后对日后会差生一些影响

这个就是写在C里的M吧,我最初碰到前台会员和后台管理员都需要编辑产品的时候也是这样做的(ThinkPHP)

\Admin\Controller\ProductController.class.php:

namespace Admin\Controller;use Api\Controller\ProductController as ApiProduct;class ProductController extends AdminController {    public function edit() {        if (I('submit')) {            $res = ApiProduct::setInfo(I());            if ($res === true) {                $alert = I('id') ? '编辑成功' : '发布成功';                $this->success($alert, '/admin/product');                exit;            } else {                $this->error($res);            }        }        I('id') && $this->data = ApiProduct::getInfo(I('id'));        $this->cate = ApiProduct::getCate();        $this->paramdata = ApiProduct::getParam();        $this->param = C('YH_PARAM');        $this->title = I('id') ? '商品编辑' : '商品发布';        $this->display('product/edit');    }}
登入後複製
登入後複製


\Api\Controller\ProductController.class.php:

    public function getInfo($id) {        $id = intval($id);        $data = M('product')->where("id = $id")->find();        $stripfield = array('name', 'name_en', 'content', 'content_en');        foreach ($stripfield as $field) {            $data[$field] = stripslashes($data[$field]);        }        $data['adddate'] = date('Y-m-d', $data['addtime']);        $data['pathArr'] = explode('-', $data['path']);        $data['img'] = ImageController::getAll(1, $id);        return $data;    }    public function setInfo($post) {        $id = intval($post['id']);        $data = array();        $data['logo'] = $post['logo'];        $data['name'] = $post['name'];        $data['name_en'] = $post['name_en'];        $cid = intval($post['cid']);        $data['path'] = self::getCatePath($cid);        list($top) = explode('-', $data['path']);        $param = C('YH_PARAM');        foreach ($param as $key => $val) {            $data[$val['field']] = $post[$val['field']][$top];        }        $data['content'] = $post['content'];        $data['content_en'] = $post['content_en'];        $data['urltb'] = format_url($post['urltb']);        $data['urlone'] = format_url($post['urlone']);        $data['urljd'] = format_url($post['urljd']);        if (empty($data['name']) || empty($data['name_en'])) {            return '商品名称不能为空';        }        if (empty($data['path'])) {            return '请选择分类';        }        if ($id) {            $data['id'] = $id;            M('product')->save($data);        } else {            $data['addtime'] = time();            $id = M('product')->add($data);        }        ImageController::addImg($post['newimg'], 1, $id);        ImageController::delImg($post['delimg']);        if (empty($data['logo'])) {            $logo = ImageController::getOne(1, $id);            M('product')->where("id = $id")->setField('logo', $logo);        }        return true;    }
登入後複製
登入後複製


我把这些通用接口都写在C里面了,但觉得实际上就是M...
比如登陆操作,有个login接口,若干个参数。传入用户名密码然后返回true或是失败原因。这个过程中要写session或是向session服务器提交。是否需要记住密码自动登陆?这个参数会影响到写cookie。是否把登陆id记录到共享内存中实现一些其他功能?我觉得这些操作都算在用户登陆的M里

是的,那些就是 M,虽然写在 C 里但依然是 M
C的作用其实就是分析用户的需求,把需求发往 M,接受 M 的返回并发往 V
C 的工作是隐蔽的,不受干涉的



MVC中M的主要是处理数据库或者业务逻辑。
更简单的说,其实把C看成商人,V看成顾客,而M则看成生产商。当生产商(M)取消后,那么意味着商人(C)就要承担生产商(M)的责任。虽然看似省略了一步,但其实只是内部消化而已,没了M,那么必然会有另一种产物来替代,来解决所有只在C中处理的业务。当然,也可以都用C,不用M或另一种替代M的方案,这也会使C的负担增大,代码也会更加复杂,代码重用性也会相对降低等等。Thinkphp中封装的一些数据库操作的方法,但未必就不是M的代替口。

个人观点,不喜勿喷~~~



你这是过去的理论,没错,现在编程语言进化,比如php。省略model层。根本没有增加C的负担,反而减小了。这是实际编程出来的结果。

下面代码就是Controler中增加和显示客服的完整代码
public function add_kefu()	{	    if(isset($_POST['id']))	    {                $data['company_id']=$_POST['id'];                $data['kefu_name']=$_POST['kefu_name'];                $data['passwd']=$_POST['passwd'];                $data['kefu_type']=$_POST['kefu_type'];                $data['kefu_name']=$_POST['kefu_name'];                $data['open_time']=time();                if($data['kefu_type']=='robot')                    $data['is_online']=1;                $id=$this->table('kefu')->insert($data);                if($id)                {                    logs('(sql:):'.$this->getLastSql());                    alert('增加客服成功:其ID为:'.$id);                }else                {                    alert('增加客户失败:原因为:'.$this->getLastError());                }	    }else	    {	       $this->company_id=isset($_GET['id'])?$_GET['id']:0;	       $this->display();	    }	}
登入後複製
登入後複製
登入後複製


实际代码之二:

//查看本公司所有客服列表	public function view_kefu()	{	    $company_id=$_GET['id'];	    $list=$this->table('kefu')->where('company_id',$company_id)->select();	    if(is_array($list))	    formatDate($list, 'open_time,last_heartbeat');	    $this->assign('list',$list);	    $this->display();	}
登入後複製
登入後複製
登入後複製

这是真实代码之二。可以看出,都是非常简单的代码。


这些代码确实简单,同时业务也不复杂~~
复杂的业务或需要复杂的sql,又该如何呢?
诚然,你上面的代码干净、利落,但是Think中用的M(),你这里用的this,或许是在C中封装的,但未必不是M的衍生物来代替Model的,复杂的东西依旧需要放到类库里或其他封装类里,也依旧是需要引用的

虽然观点不一致,但还是很佩服楼主的,有自己的想法和坚持~



复杂的东西,当然需要另外有类。肯定的。

这个就是写在C里的M吧,我最初碰到前台会员和后台管理员都需要编辑产品的时候也是这样做的(ThinkPHP)

\Admin\Controller\ProductController.class.php:

namespace Admin\Controller;use Api\Controller\ProductController as ApiProduct;class ProductController extends AdminController {    public function edit() {        if (I('submit')) {            $res = ApiProduct::setInfo(I());            if ($res === true) {                $alert = I('id') ? '编辑成功' : '发布成功';                $this->success($alert, '/admin/product');                exit;            } else {                $this->error($res);            }        }        I('id') && $this->data = ApiProduct::getInfo(I('id'));        $this->cate = ApiProduct::getCate();        $this->paramdata = ApiProduct::getParam();        $this->param = C('YH_PARAM');        $this->title = I('id') ? '商品编辑' : '商品发布';        $this->display('product/edit');    }}
登入後複製
登入後複製


\Api\Controller\ProductController.class.php:

    public function getInfo($id) {        $id = intval($id);        $data = M('product')->where("id = $id")->find();        $stripfield = array('name', 'name_en', 'content', 'content_en');        foreach ($stripfield as $field) {            $data[$field] = stripslashes($data[$field]);        }        $data['adddate'] = date('Y-m-d', $data['addtime']);        $data['pathArr'] = explode('-', $data['path']);        $data['img'] = ImageController::getAll(1, $id);        return $data;    }    public function setInfo($post) {        $id = intval($post['id']);        $data = array();        $data['logo'] = $post['logo'];        $data['name'] = $post['name'];        $data['name_en'] = $post['name_en'];        $cid = intval($post['cid']);        $data['path'] = self::getCatePath($cid);        list($top) = explode('-', $data['path']);        $param = C('YH_PARAM');        foreach ($param as $key => $val) {            $data[$val['field']] = $post[$val['field']][$top];        }        $data['content'] = $post['content'];        $data['content_en'] = $post['content_en'];        $data['urltb'] = format_url($post['urltb']);        $data['urlone'] = format_url($post['urlone']);        $data['urljd'] = format_url($post['urljd']);        if (empty($data['name']) || empty($data['name_en'])) {            return '商品名称不能为空';        }        if (empty($data['path'])) {            return '请选择分类';        }        if ($id) {            $data['id'] = $id;            M('product')->save($data);        } else {            $data['addtime'] = time();            $id = M('product')->add($data);        }        ImageController::addImg($post['newimg'], 1, $id);        ImageController::delImg($post['delimg']);        if (empty($data['logo'])) {            $logo = ImageController::getOne(1, $id);            M('product')->where("id = $id")->setField('logo', $logo);        }        return true;    }
登入後複製
登入後複製


我把这些通用接口都写在C里面了,但觉得实际上就是M...
比如登陆操作,有个login接口,若干个参数。传入用户名密码然后返回true或是失败原因。这个过程中要写session或是向session服务器提交。是否需要记住密码自动登陆?这个参数会影响到写cookie。是否把登陆id记录到共享内存中实现一些其他功能?我觉得这些操作都算在用户登陆的M里

是的,你实际编程也是在和我一样。
我写的框架,从底层就支持这些了。
你的结果和我一样。

楼主的那两段代码实际都是业务逻辑,属于M的范畴
作为实际的项目,当然可以这样写
但如果是继承于 model 的话,也就 D('add_kefu')、D('view_kefu') 这样就可以了
框架与实际项目的区别在于框架总是要与未知的对象打交道,所以任何一个环节都不能写死
实际项目只关心具体的业务,但写死后对日后会差生一些影响



是的,那些就是 M,虽然写在 C 里但依然是 M
C的作用其实就是分析用户的需求,把需求发往 M,接受 M 的返回并发往 V
C 的工作是隐蔽的,不受干涉的



我认为:C处理业务逻辑。M处理数据相关。

你一定要这么认为,我也没办法
但是业务和数据是分不开的,不同的业务处理不同的数据。
这一点你不会否认吧?

你一定要这么认为,我也没办法
但是业务和数据是分不开的,不同的业务处理不同的数据。
这一点你不会否认吧?



MVC各如何处理,本就没有标准。老徐,你这么高手,天天混论坛,不无聊么?出来开发开发程序啊。
我认为业务和数据是可以分开的。C处理业务,M处理数据。真正复杂的处理数据时,可以另创建类。

那你干脆打混战,还讨论什么架构干什么?
快 70 了精力有限,偶尔接个小项目做做。泡论坛是为了不落伍,不动动脑筋不就痴呆了?


Laravel的作者写了一本书叫《From Apprentice To Artisan》,里面有个章节叫。好像楼主已经到了跟大神同样的境界了。楼主可以去看看这本书。。。

具体没看懂,作者开发的框架里面有非常明确的MVC文件夹。但是写的书却推翻的了这个观点。楼主有兴趣研究那个吧。thinkphp已经不属于你研究的范畴了。

Laravel的作者写了一本书叫《From Apprentice To Artisan》,里面有个章节叫。好像楼主已经到了跟大神同样的境界了。楼主可以去看看这本书。。。

具体没看懂,作者开发的框架里面有非常明确的MVC文件夹。但是写的书却推翻的了这个观点。楼主有兴趣研究那个吧。thinkphp已经不属于你研究的范畴了。


刚才百度了下Laravel代码。model代码几乎和我一样。但我的代码比他还要更艺术家。更简单,更漂亮。
像他这样实现框架,当然是不需要model的。和我一样的思路。
 真的可以Byby了。
以php水平来说。ThinkPhP作者已经是非常高的了。他有10多年php开发经验。

Laravel 已不是 MVC 的范畴了(其实各种架构、设计模式间并没有明显的界限)
虽然他也按 MVC 描述了一些特征
要说他是三层的话,界限似乎又划分的不那么明确。在视图里可以访问数据库,这在三层中是绝不允许的
他的路由实际是 REST 模式的典型应用。
由于 PEST 是无状态的,显然并不适合做需要用户认证的应用系统
于是 Laravel 就必须破坏一些约定

总之 Laravel 仍然是一个大杂烩,其实其他框架也都是大杂烩

框架没有完全的好坏之分,只有适合不适合而已。。
楼主的这个小改革,是没有遇到复杂的业务吧。。
我们这边是在M和C之间增加了module,C只是串联各个module而已,module操作model来实现。。对于各个业务模块的耦合度很低,感觉确实很好用。。

框架没有完全的好坏之分,只有适合不适合而已。。
楼主的这个小改革,是没有遇到复杂的业务吧。。
我们这边是在M和C之间增加了module,C只是串联各个module而已,module操作model来实现。。对于各个业务模块的耦合度很低,感觉确实很好用。。


恕我直言,你的第一句看是正确,确实完全错误!
是不是事情也没有对错?只是立场不同?要监狱干嘛?
恕我直言,兄弟你的判断力还极差!

根据楼主的思想,我已经完全实现了这种框架,完全活力model层。已经在2项目中使用,同时根据此思想框架,做了一个自动生成代码的系统。实现得很完美漂亮。
暂时没有发现不好。目的已经达到。
准备结贴!

框架没有完全的好坏之分,只有适合不适合而已。。
楼主的这个小改革,是没有遇到复杂的业务吧。。
我们这边是在M和C之间增加了module,C只是串联各个module而已,module操作model来实现。。对于各个业务模块的耦合度很低,感觉确实很好用。。



框架没有完全的好坏之分,只有适合不适合而已。。这句话我有专门文章讨论。
module应该在C&&V之上吧。我的框架就是在module下才有这些,module只是一种思想。非程序。由框架,架构实现。

I learnt a word today: Narcissism

I learnt a word today: Narcissism


I also learnt a word today: wuzhi&&youzhi.


I learnt a word today: Narcissism


I also learnt a word today: wuzhi&&youzhi.

nice to see you again, former fortune 500 PM!


I learnt a word today: Narcissism


I also learnt a word today: wuzhi&&youzhi.

P.S., ur pinyin and English mashup is so cool! Wait a second, did you just copy & paste what I wrote and then appended your pinyin? That's not cool. That sucks for a former fortune 500 PM!!!



I learnt a word today: Narcissism


I also learnt a word today: wuzhi&&youzhi.

P.S., ur pinyin and English mashup is so cool! Wait a second, did you just copy & paste what I wrote and then appended your pinyin? That's not cool. That sucks for a former fortune 500 PM!!!

sucks uself,guys like P




I learnt a word today: Narcissism


I also learnt a word today: wuzhi&&youzhi.

P.S., ur pinyin and English mashup is so cool! Wait a second, did you just copy & paste what I wrote and then appended your pinyin? That's not cool. That sucks for a former fortune 500 PM!!!

sucks uself,guys like P

nice try, former fortune 500 PM. You are right. ur English sucks

                $data['company_id']=$_POST['id'];
                $data['kefu_name']=$_POST['kefu_name'];
                $data['passwd']=$_POST['passwd'];
                $data['kefu_type']=$_POST['kefu_type'];
                $data['kefu_name']=$_POST['kefu_name'];
                $data['open_time']=time();

这种已经很复杂了啊, 也许你要说这都是代码生成器生成的, 但是修改数据库表结构的造成的改动呢, 还是得一个字段一个字段的写, 这只是一个缩引, HTML展示页面也要一个一个写么?

                $data['company_id']=$_POST['id'];
                $data['kefu_name']=$_POST['kefu_name'];
                $data['passwd']=$_POST['passwd'];
                $data['kefu_type']=$_POST['kefu_type'];
                $data['kefu_name']=$_POST['kefu_name'];
                $data['open_time']=time();

这种已经很复杂了啊, 也许你要说这都是代码生成器生成的, 但是修改数据库表结构的造成的改动呢, 还是得一个字段一个字段的写, 这只是一个缩引, HTML展示页面也要一个一个写么?



现在全部是机器生成,前台后台。

根据此思想的框架已经开发完成。

已经发布开发版本:http://250.sz400.net/yuyan_kaifa.rar
包含完整的Demo和详细说明文档(没100%完整!)。

1、此次发布为开发版本 仅供测试功能使用(安全等忽略)
2、相关文档在  doc目录
3、数据库文件在 data目录
4、配置文件在App/config.php 文件
5、项目中App\User 和System 100%纯机器生成。非人工手写。
6、App\Default部分也为生成,不过有人工略有修改(1个小时左右)。这也就是为什么没有将代码机器人发布的原因。

运行步骤:
先执行:YuYan.sql
再执行:data.sql
再修改:App\config 里数据库配置

再执行此目录

登录用户名:13510668888 111111

因发布时间极为短暂,所以,错误之处难免,肯请各位批评指正。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
威爾R.E.P.O.有交叉遊戲嗎?
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

在PHP API中說明JSON Web令牌(JWT)及其用例。 在PHP API中說明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

描述紮實的原則及其如何應用於PHP的開發。 描述紮實的原則及其如何應用於PHP的開發。 Apr 03, 2025 am 12:04 AM

SOLID原則在PHP開發中的應用包括:1.單一職責原則(SRP):每個類只負責一個功能。 2.開閉原則(OCP):通過擴展而非修改實現變化。 3.里氏替換原則(LSP):子類可替換基類而不影響程序正確性。 4.接口隔離原則(ISP):使用細粒度接口避免依賴不使用的方法。 5.依賴倒置原則(DIP):高低層次模塊都依賴於抽象,通過依賴注入實現。

如何在系統重啟後自動設置unixsocket的權限? 如何在系統重啟後自動設置unixsocket的權限? Mar 31, 2025 pm 11:54 PM

如何在系統重啟後自動設置unixsocket的權限每次系統重啟後,我們都需要執行以下命令來修改unixsocket的權限:sudo...

解釋PHP中晚期靜態結合的概念。 解釋PHP中晚期靜態結合的概念。 Mar 21, 2025 pm 01:33 PM

文章討論了PHP 5.3中介紹的PHP中的晚期靜態結合(LSB),允許靜態方法的運行時間分辨率調用以更靈活的繼承。 LSB的實用應用和潛在的觸摸

如何用PHP的cURL庫發送包含JSON數據的POST請求? 如何用PHP的cURL庫發送包含JSON數據的POST請求? Apr 01, 2025 pm 03:12 PM

使用PHP的cURL庫發送JSON數據在PHP開發中,經常需要與外部API進行交互,其中一種常見的方式是使用cURL庫發送POST�...

框架安全功能:防止漏洞。 框架安全功能:防止漏洞。 Mar 28, 2025 pm 05:11 PM

文章討論了框架中的基本安全功能,以防止漏洞,包括輸入驗證,身份驗證和常規更新。

自定義/擴展框架:如何添加自定義功能。 自定義/擴展框架:如何添加自定義功能。 Mar 28, 2025 pm 05:12 PM

本文討論了將自定義功能添加到框架上,專注於理解體系結構,識別擴展點以及集成和調試的最佳實踐。

See all articles