MVC只是一种设计模式而已,一度被认为Model 1,也就是服务器语句与HTML语句杂糅的php,其实不用任何框架,仅仅利用原生态的JavaScript Ajax也可以对其进行MVC设计。由于什么都没有用,因此对IE6的兼容性是非常强的。还是《【php】数据库的增删改查和php与javascript之间的交互》(点击打开链接)那个页面的,对数据库增删改查的内容,希望各位能推广到整个网站。
一、基本目标
整个网页实现效果如下,用户输入完表单马上就有效果。
二、基本思想
首先,在test数据库中有一张这样的用户信息表,建表的时候注意检查一下那些数据库字段的编码是否是utf-8,一些Mysql在安装时候没有改默认的编码latin1的,不然一会儿你打死无法存中文。
然后,整个网页工程结构如下图:
在view.php中网页中不进行任何刷新,利用原生态的JavaScript Ajax,直接完成V-C层的交互。C-M层的交互通过include语句,引入M层的业务逻辑类中方法,通过类参数的传递完成。
同时,C、M层的php拒绝直接输入网址访问。这里不像JSP或者ASP,C层、M层都是编译之后的JAVA文件或者C#文件,根本就访问不了。我们还要对其进行保护。
三、制作过程
1、View层就一个简单的View.php,其布局如下,没什么好说的,非常简单的HTML布局。同时,注意,本页面:
(1)没有设置表单,所有表单提交的动作,通过button触发相应的JavaScript而触发。
(2)各个组件的ID,一会儿在JavaScript用到。其中用户信息表、修改ID的下拉框都是通过下面的脚本Ajax而加载的。
(3)布局中,包括一会儿的脚本在内没有任何php代码,便于各位布局。你把后缀名改成.html也能够正常运行。什么叫做真正的View层?这就是了,没有任何的服务器代码。
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>用户信息表</title>用户信息表如下:<div id="result"></div><hr>插入数据<br>用户名:<input type="text" name="username">密码:<input type="text" name="password"><button onclick="insert()">GO!</button><hr>修改数据<br><select id="userid" name="userid"></select><select name="rowname"> <option value="username">用户名</option> <option value="password">密码</option></select><input type="text" name="rowtext"><button onclick="update()">GO!</button>
其实整个View层的精髓在于下面的JavaScript脚本。View层就无须使用到Xajax这个插件了,《【php】Xajax Helloworld》(点击打开链接)。直接用原生态的JavaScript写。虽然代码量比起JQuery等前端框架较多,记住不容易。从建立Ajax对象,设置Ajax请求头,处理Ajax文本都要自己写,但在开发过程中,只是复制粘贴而已。因此可以观察到,所有的Ajax交互函数都大同小易。拿ForAllUserInfo();这个函数来重点说明怎么V-C层怎么通过Ajax交互。
<script>//首先,本页面一加载就调用两个函数,加载本页。ForAllUserInfo();ForTotal();//创建Ajax对象,不同浏览器有不同的创建方法,其实本函数就是一个简单的new语句而已。function createXMLHttpRequest(XMLHttpRequest){ var XMLHttpRequest; if(window.XMLHttpRequest){ XMLHttpRequest=new XMLHttpRequest(); } else if(window.ActiveXObject){ try{ XMLHttpRequest=new ActiveXObject("Msxml2.XMLHTTP"); } catch(e){ XMLHttpRequest=new ActiveXObject("Microsoft.XMLHTTP"); } } return XMLHttpRequest;}function ForAllUserInfo(){ var XMLHttpRequest=createXMLHttpRequest(XMLHttpRequest); //指明相应页面 var url="dbselect.php"; XMLHttpRequest.open("POST",url,true); //这里没法解释,你所有JavaScript的请求头都这样写就对了,不会乱码 XMLHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //对于dbselect.php,本view.php没有任何参数给你。 XMLHttpRequest.send(null); //对于返回结果怎么处理的问题 XMLHttpRequest.onreadystatechange=function(){ //这个4代表已经发送完毕之后 if(XMLHttpRequest.readyState==4){ //200代表正确收到了返回结果 if(XMLHttpRequest.status==200){ //那么id为result的div,就是整个dbselect.php页面了。 document.getElementById("result").innerHTML=XMLHttpRequest.responseText; } else{ //如果不能正常接受结果,你肯定是断网,或者我的服务器关掉了。 alert("网络连接中断!"); } } };}function ForTotal(){ var XMLHttpRequest=createXMLHttpRequest(XMLHttpRequest); var url="dbtotal.php"; XMLHttpRequest.open("POST",url,true); XMLHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); XMLHttpRequest.send(null); XMLHttpRequest.onreadystatechange=function(){ if(XMLHttpRequest.readyState==4){ if(XMLHttpRequest.status==200){ var total=parseInt(XMLHttpRequest.responseText); //先把修改ID的下拉列表清空 document.getElementById("userid").innerHTML=""; if(total>0){ for(var i=1;i<total+1;i++){ //javascript增加节点过程,数据库有多少项就填充多少个ID给用户修改。 var selectnode=document.createElement("option"); selectnode.value=i; selectnode.innerHTML=i; document.getElementById("userid").appendChild(selectnode); } } } else{ alert("网络连接中断!"); } } }; }function insert(){ //从输入框拿来插入数据的所有表单 var username=document.getElementById("username").value; var password=document.getElementById("password").value; //如果用户输入的值不为空,则执行Ajax if(username!=""&&password!=""){ var XMLHttpRequest=createXMLHttpRequest(XMLHttpRequest); var url="dbinsert.php"; XMLHttpRequest.open("POST",url,true); XMLHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //这里View层的View.php需要发送两个参数给Controll层的dbinsert.php处理 XMLHttpRequest.send("username="+username+"&password="+password); XMLHttpRequest.onreadystatechange=function(){ if(XMLHttpRequest.readyState==4){ if(XMLHttpRequest.status==200){ //添加数据成功,则部分刷新View层的用户信息表与修改ID的下拉列表 ForAllUserInfo(); ForTotal(); } else{ alert("网络连接中断!"); } } }; } else{ alert("不得为空!"); }}//这里修改数据与insert()同理function update(){ var userid=document.getElementById("userid").value; var rowname=document.getElementById("rowname").value; var rowtext=document.getElementById("rowtext").value; if(userid!=""&&rowname!=""&&rowtext!=""){ var XMLHttpRequest=createXMLHttpRequest(XMLHttpRequest); var url="dbupdate.php"; XMLHttpRequest.open("POST",url,true); XMLHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); XMLHttpRequest.send("userid="+userid+"&rowname="+rowname+"&rowtext="+rowtext); XMLHttpRequest.onreadystatechange=function(){ if(XMLHttpRequest.readyState==4){ if(XMLHttpRequest.status==200){ ForAllUserInfo(); ForTotal(); } else{ alert("网络连接中断!"); } } }; } else{ alert("不得为空!"); }}</script>
2、Controll层
Controll层的页面都与View层中的JavaScript函数一一对应。
比如dbupdate.php就对应view.php中的update()函数。通过如下两句对应起来。
var url="dbupdate.php";XMLHttpRequest.open("POST",url,true);(1)dbupdate.php
非常简单的页面,拿到前端送过来的两个数据,则进行与Model层的交互,完成数据库的操作。修改数据库,数据库是不会返回任何结果的,因此也没有什么数据给前端的。如果拿不到前端送过来的参数,那一定是恶意用户,通过输入网址非正常打开此页。C层M层一般是不给你打开的。
<?php include_once("db.php"); if(empty($_REQUEST["userid"])){ header("Content-type: text/html; charset=utf-8"); echo "请正常打开此页!"; } else{ $db=new db(); $userid=$_REQUEST["userid"]; $rowname=$_REQUEST["rowname"]; $rowtext=$_REQUEST["rowtext"]; $db->modify("update user set ".$rowname."='".$rowtext."' where id=".$userid.";"); }?>
(2)dbinsert.php
插入数据同样的道理了,不再赘述。对应于前端的insert()函数
<?php include_once("db.php"); if(empty($_REQUEST["username"])){ header("Content-type: text/html; charset=utf-8"); echo "请正常打开此页!"; } else{ $db=new db(); $username=$_REQUEST["username"]; $password=$_REQUEST["password"]; $db->modify("insert into user(username,password) values ('".$username."','".$password."');"); }?>(3)dbtotal.php
这一页是用来查询数据库有多少条结果,我们在修改数据的下拉列表就要提供给用户多少个ID,给用户指定修改。
对应于view.php中的ForTotal()函数。这一页是有返回结果的。因此dbtotal.php就把这个结果用echo打印出来,前端通过:
var total=parseInt(XMLHttpRequest.responseText);这一句中的XMLHttpRequest.responseText拿到,前端的JavaScript必须强制指明这是数字,否则则出现7+1=71的神运算。JavaScript把数字当字符串了,也没办法了,毕竟所有变量都是var。php则都是美元$。
这一页就无须保护了,毕竟肯定要给用户看的。
<?php include_once("db.php"); $db=new db(); $total=$db->getTotal(); echo $total;?>(4)dbselect.php
这一页其实和dbtotal.php一样,不过变成了构造一个表格,送给前端View.php的ForAllUserInfo()。ForAllUserInfo()得到的数据其实一段HTML文本,直接通过.innerHTML放上去就可以了。
<?php include_once("db.php"); $db=new db(); $user=$db->getAllUserInfo();?>
ID | 用户名 | 密码 | ".$user[$i]['id']." | ".$user[$i]['username']." | ".$user[$i]['password']." | "; }?>
---|
这页有HTML打死都不能与PHP代码混在一起的强迫症患者,请自行把所有HTML的代码,给成echo输出,反正我就只能给出这样的一个方案了。
3、Model层
这一层的所有方法都与C层的页面存在对应关系。
首先都公用一个数据库连接函数。之后各自在方法中调用,最后各自查询完毕则关闭这个连接。
然后,可以注意到上面的Controll层的dbupdate.php与dbinsert.php公用此类的一个方法。这主要是考虑到,都是传递一个SQL语句过来,然后没有返回结果,因此可以合在一起了。而查询数据库的所有数据与查询数据库的数据数量的返回结果是不同的,因此分开两个方法。
<?phpfunction createCon(){ //数据库的地址是localhost:3306,数据库用户名(第二项)是root,数据库密码(第三项)是root $con=mysql_connect("localhost","root","root"); if(!$con){ die("连接失败!"); } //要操作test数据库 mysql_select_db("test",$con); //防止乱码 mysql_query("set names utf8;"); return $con;}class db{ public function getAllUserInfo(){ $con=createCon(); $result=mysql_query("select * from user;"); //如果查询的结果多,就放到一个二维数组里面,返回给Controll层 //Controll层再对这个二维数组一一处理。 //起始这个二维数组不就相当于JSP中的ArrayList吗?^_^ $userList=array(); for($i=0;$row=mysql_fetch_array($result);$i++){ $userList[$i]['id']=$row['id']; $userList[$i]['username']=$row['username']; $userList[$i]['password']=$row['password']; } mysql_close($con); return $userList; } public function getTotal(){ $con=createCon(); $result=mysql_query("select count(*) as total from user;"); //如果返回结果只有一个,那就直接这样取数据。 $row=mysql_fetch_array($result); mysql_close($con); return $row['total']; } public function modify($sql){ //对于那些传sql过来没有返回结果的方法,归纳到同一类 $con=createCon(); mysql_query($sql); mysql_close($con); }}?>
四、总结与展望
上面的制作过程最好合在一起看,反正我只能这样分层贴了。V-C,C-M一直在交互,从未被割裂,根本停不下来。对比与《【php】数据库的增删改查和php与javascript之间的交互》(点击打开链接)这个以MODEL1模式创作的工程,页面虽然增多,但是模块更加地清晰。
反正MVC仅仅是一种设计模式、设计思想而已,在PHP同样也能够实现。在JSP对这种模式的吹嘘是言过其实了,主要是JSP的部分创作者,不停地对于框架的使用,而忘记了这门语言的本质。
我觉得这个例子,再次证明了语言只是思想表达的载体。无插件无框架,纯HTML+CSS与纯JavaScript加PHP就能够实现,兼容IE6。如果你打包一样,放上防注入函数,完全可以成为自己的框架的。
对比与JSP与ASP,我在写PHP的时候更加舒服,告别了MyEclipse/Eclipse与Visual Studio的卡爆,用着早已被批得一毛不是Dreamwaver,甚至还可以用记事本写着网页,半点不卡。一台垃圾配置的Winxp就能够创造出好的网站。关键是你的语言基本功问题了。少做点喷子,多做点工程。多接触几门编程语言。

PHP仍然流行的原因是其易用性、灵活性和强大的生态系统。1)易用性和简单语法使其成为初学者的首选。2)与web开发紧密结合,处理HTTP请求和数据库交互出色。3)庞大的生态系统提供了丰富的工具和库。4)活跃的社区和开源性质使其适应新需求和技术趋势。

PHP和Python都是高层次的编程语言,广泛应用于Web开发、数据处理和自动化任务。1.PHP常用于构建动态网站和内容管理系统,而Python常用于构建Web框架和数据科学。2.PHP使用echo输出内容,Python使用print。3.两者都支持面向对象编程,但语法和关键字不同。4.PHP支持弱类型转换,Python则更严格。5.PHP性能优化包括使用OPcache和异步编程,Python则使用cProfile和异步编程。

PHP主要是过程式编程,但也支持面向对象编程(OOP);Python支持多种范式,包括OOP、函数式和过程式编程。PHP适合web开发,Python适用于多种应用,如数据分析和机器学习。

PHP起源于1994年,由RasmusLerdorf开发,最初用于跟踪网站访问者,逐渐演变为服务器端脚本语言,广泛应用于网页开发。Python由GuidovanRossum于1980年代末开发,1991年首次发布,强调代码可读性和简洁性,适用于科学计算、数据分析等领域。

PHP适合网页开发和快速原型开发,Python适用于数据科学和机器学习。1.PHP用于动态网页开发,语法简单,适合快速开发。2.Python语法简洁,适用于多领域,库生态系统强大。

PHP在现代化进程中仍然重要,因为它支持大量网站和应用,并通过框架适应开发需求。1.PHP7提升了性能并引入了新功能。2.现代框架如Laravel、Symfony和CodeIgniter简化开发,提高代码质量。3.性能优化和最佳实践进一步提升应用效率。

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

PHP类型提示提升代码质量和可读性。1)标量类型提示:自PHP7.0起,允许在函数参数中指定基本数据类型,如int、float等。2)返回类型提示:确保函数返回值类型的一致性。3)联合类型提示:自PHP8.0起,允许在函数参数或返回值中指定多个类型。4)可空类型提示:允许包含null值,处理可能返回空值的函数。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

SublimeText3汉化版
中文版,非常好用

Dreamweaver Mac版
视觉化网页开发工具

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器