长久以来,编程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的。和我一样的思路。
以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
因发布时间极为短暂,所以,错误之处难免,肯请各位批评指正。