목차
回复讨论(解决方案)
백엔드 개발 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 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

JWT (JSON Web Tokens) 및 PHP API의 사용 사례를 설명하십시오. JWT (JSON Web Tokens) 및 PHP API의 사용 사례를 설명하십시오. Apr 05, 2025 am 12:04 AM

JWT는 주로 신분증 인증 및 정보 교환을 위해 당사자간에 정보를 안전하게 전송하는 데 사용되는 JSON을 기반으로 한 개방형 표준입니다. 1. JWT는 헤더, 페이로드 및 서명의 세 부분으로 구성됩니다. 2. JWT의 작업 원칙에는 세 가지 단계가 포함됩니다. JWT 생성, JWT 확인 및 Parsing Payload. 3. PHP에서 인증에 JWT를 사용하면 JWT를 생성하고 확인할 수 있으며 사용자 역할 및 권한 정보가 고급 사용에 포함될 수 있습니다. 4. 일반적인 오류에는 서명 검증 실패, 토큰 만료 및 대형 페이로드가 포함됩니다. 디버깅 기술에는 디버깅 도구 및 로깅 사용이 포함됩니다. 5. 성능 최적화 및 모범 사례에는 적절한 시그니처 알고리즘 사용, 타당성 기간 설정 합리적,

PHP에서 늦은 정적 결합의 개념을 설명하십시오. PHP에서 늦은 정적 결합의 개념을 설명하십시오. Mar 21, 2025 pm 01:33 PM

기사는 PHP 5.3에 도입 된 PHP의 LSB (Late STATIC BING)에 대해 논의하여 정적 방법의 런타임 해상도가보다 유연한 상속을 요구할 수있게한다. LSB의 실제 응용 프로그램 및 잠재적 성능

프레임 워크 보안 기능 : 취약점 보호. 프레임 워크 보안 기능 : 취약점 보호. Mar 28, 2025 pm 05:11 PM

기사는 입력 유효성 검사, 인증 및 정기 업데이트를 포함한 취약점을 방지하기 위해 프레임 워크의 필수 보안 기능을 논의합니다.

프레임 워크 사용자 정의/확장 : 사용자 정의 기능을 추가하는 방법. 프레임 워크 사용자 정의/확장 : 사용자 정의 기능을 추가하는 방법. Mar 28, 2025 pm 05:12 PM

이 기사에서는 프레임 워크에 사용자 정의 기능 추가, 아키텍처 이해, 확장 지점 식별 및 통합 및 디버깅을위한 모범 사례에 중점을 둡니다.

PHP의 CURL 라이브러리를 사용하여 JSON 데이터가 포함 된 게시물 요청을 보내는 방법은 무엇입니까? PHP의 CURL 라이브러리를 사용하여 JSON 데이터가 포함 된 게시물 요청을 보내는 방법은 무엇입니까? Apr 01, 2025 pm 03:12 PM

PHP 개발에서 PHP의 CURL 라이브러리를 사용하여 JSON 데이터를 보내면 종종 외부 API와 상호 작용해야합니다. 일반적인 방법 중 하나는 컬 라이브러리를 사용하여 게시물을 보내는 것입니다 ...

확실한 원칙과 PHP 개발에 적용되는 방법을 설명하십시오. 확실한 원칙과 PHP 개발에 적용되는 방법을 설명하십시오. Apr 03, 2025 am 12:04 AM

PHP 개발에서 견고한 원칙의 적용에는 다음이 포함됩니다. 1. 단일 책임 원칙 (SRP) : 각 클래스는 하나의 기능 만 담당합니다. 2. Open and Close Principle (OCP) : 변경은 수정보다는 확장을 통해 달성됩니다. 3. Lisch의 대체 원칙 (LSP) : 서브 클래스는 프로그램 정확도에 영향을 미치지 않고 기본 클래스를 대체 할 수 있습니다. 4. 인터페이스 격리 원리 (ISP) : 의존성 및 사용되지 않은 방법을 피하기 위해 세밀한 인터페이스를 사용하십시오. 5. 의존성 반전 원리 (DIP) : 높고 낮은 수준의 모듈은 추상화에 의존하며 종속성 주입을 통해 구현됩니다.

Reactphp의 비 차단 기능은 정확히 무엇입니까? 차단 I/O 작업을 처리하는 방법은 무엇입니까? Reactphp의 비 차단 기능은 정확히 무엇입니까? 차단 I/O 작업을 처리하는 방법은 무엇입니까? Apr 01, 2025 pm 03:09 PM

Reactphp의 비 블로킹 기능에 대한 Reactphp의 심층적 인 해석의 비 차단 기능에 대한 공식 소개는 많은 개발자들의 질문을 불러 일으켰습니다.

See all articles