公司通讯录开发
三、公司通讯录后台开发
我设计的公司通讯录是先人工输入到后台,然后前台进行绑定、查询、更新等操作,今天先讲后台录入这块,主要包括部门设置和员工管理两个页面,所有的开发都在sae的代码管理中进行,所以请进入SAE的应用里的代码管理。
在开发前我们先要上传一个文件“base-class.php”,这个文件主要是用来做传递参数的过滤以及格式验证,比如是否邮箱、手机等是否正确输入
3.1、部门设置
第一个要开发的模块是部门设置,一般的公司架构都是多层级的,比如总经理-》部门-》小组,因此我们的部门设置里也要具备多层级的功能。
首先第一个页面部门录入页面,我们新建一个文件,命名为class_add.php,主要实现功能为添加和修改部门名称及上下级分类。代码如下:
后台页面是需要在浏览器里打开操作的,因此需要有HTML代码部分,一般正规开发都会将数据操作、逻辑操作、网页模板分离,我这里图方便就混排了。
这个页面实现的是两个功能:一是新增部门,二是修改部门,两个是放在同一个页面里的,那么如何判断是新增操作还是修改操作呢?根据url里是否有传递过来部门的序号即ID号,如果有就是修改,没有就是新增,具体后面会有解释。
码解释如下:
第1-6行代码是html语言,头部格式都是固定的,其中第4行是告诉浏览器这个网页是utf-8编码的,第5行是网页的名字,会显示在浏览器顶部,当然一般还有两个重要参数,一个是Keyword,就是关键字,还有一个是Description,是网页说明,这两个都是做SEO时用的,这里不需要就没写了。
PS:HTML 语言通常被称为 HTML 标签 (HTML tag),HTML 标签是由尖括号包围的关键词,比如 <html>,通常是成对出现的,比如 <b> 和 </b>,标签对中的第一个标签是开始标签,第二个标签是结束标签。
第7行是html页面的主体的开始标签<body>,浏览器会将<body>与</body>之间的内容显示在浏览器页面。
第9行是开始是php的程序处理。
第10行是加载前面让大家上传的base-class.php,后面会调用里面的函数。
第13行是新建一个数据库操作类,由于是在sae环境下开发,所以我直接用了sae提供的mysql类,这样就免去数据库链接什么乱七八糟的了。当然原始提供的函数并不丰富,也不适合代码迁移,一般是需要去封装一层的,我这里先偷个懒吧,同时也方便大家学习。
第16行是获取通过URL传递的参数class_id,即部门的序号。这里有个intval函数是将变量转化成整数,如果class_id值为空则intval(class_id)=0;如果class_id值为1则intval(class_id)=1;如果如果class_id值为abc12则intval(class_id)=0,这里的作用是将转换数据格式同时防止注入。
PS:程序中数据传递主要通过两种方式获取GET和POST,前者是获取URL的参数值,后者是获取表单传递的数据,前者安全性低效率高适合传输一些小数据,后者安全性高效率低适合传输一些大数据。
第19行是获取表单提交的参数action的值,用来判断是否提交了表单。
第20、21行是用来过滤操作变量action的值,由于action是字符串,所以得用字符串过滤规则,其中un_script_code是去除js代码,un_html是去除html代码。
第24行判断class_id是否有值,如果有值即非0则表示修改序号为class_id的部门信息;
第26行根据class_id从数据库中提取详细数据,提取单条记录我们使用sae的mysql类下的getLine函数,我们前面已经新建了一个mysql类命名为$mysql,所以这里就是$mysql->getLine,后面括号里就是一句sql查询语句,意思是
select(选择)
*(所有字段)
from(从)
class(名字为class的表里)
where(符合条件为)
class_id=$class_id(class_id字段的值等于$class_id的数据),获取到的数据是一个数组,赋值给$class_value。
第27行为判断是否获取到class_id=$class_id的记录,!$class_value表示该值为空没有获取到,那么就执行一个警告。
第29行输出一个JS语句,这个语句里<script>是js的标签,alert是警告函数,用法是alert("提示的文字内容"),history.back();是返回上一页 ,整句话就是警告没有该条记录,点击确定后返回到上一页,中断程序执行。
第35行是判断$action是否等于update,即是否提交了表单。
第38行到第44行是获取从表单提交过来的数据,并进行格式化,其中$old_class_id的值来源是在修改条件下,url传递过来的class_id值会在存放在一个隐藏的input元素中,然后表单提交时又将该值传递回来,也就是$old_class_id其实是url传递过来那个class_id的值。
第46行是获取当前时间,time()之前有讲过是获取时间戳,是一个10位的整数,然后用date函数格式化成年月日时分秒格式,后面要写到数据库里。
第48行是判断$old_class_id是否为空,即修改模式还是新增模式,如果有值则为修改模式。
第51,52行,更新数据的sql语言,
update 修改
class 名字是class的数据表
set 设置
class_name='$class_name', 部门名修改
class_fid='$class_fid',上级部门修改
edittime='$nowtime' 修改时间
where class_id=$old_class_id (符合条件class_id字段的值等于$class_id的数据)
大家可以看到这里修改的其实就是部门名字、上级部门,同时记录下修改的时间,
由于sql语句本身就是一个字符串,所以当赋值的变量为字符串需要用单引号包括起来,否则执行会出错。
第53行是执行上面的sql语句,只运行语句不返回结果,函数为runSql。
第58、59行,新增数据的sql语句,
insert into 插入数据到
class 名字是class的数据表
(class_name,class_fid,addtime,edittime,status)字段名
values 赋值为
('$class_name', '$class_fid','$nowtime','$nowtime',1)对应的值
这里可以注意到字段名和数据是一一对应的,分别是部门名、上级部门序号、添加时间、修改时间和记录状态(新增的设为1表示正常)。
第63行,runSql函数虽然不返回数据结果但是会返回一个执行信息,$mysql->errno() 如果是0则表示成功,否则不成功。
第65行执行不成功,输出警告信息。
第70行执行成功,输出成功提示,然后页面刷新,“location=”是JS函数,用来改变当前url并载入,链接地址为“class_add.php”,我在后面又加了class_id=$old_class_id,效果会变为如果是修改模式则重新加载一次修改后的部门信息,如果是新增模式则清空表单可以继续新增。
第76行提取所有有效的部门信息,主要是用来做上级部门选择用的,提取多条记录使用的函数是getData,sql语句的意思是:
select 选择
class_name,class_id 部门名和部门ID
from 从
class 名字是class的数据表
where 符合
status=1 状态为正常的数据
order by class_fid asc 按照上级部门ID的升序排序,order by 表示排序,排序的字段是class_fid,asc是升序即从小到大。
第80行开始是HTML代码,H3是标题标签,这里写了这页面的标题是“部门添加/修改”,后面跟的一个链接地址用来返回到部门列表页面,a标签是链接标签,href后面跟的是链接地址,a开闭标签之间是页面显示文字。
第82行表单标签开始,介绍下参数action是指当提交表单时,向何处发送表单数据,这里是填写URL,我这里写了?号,指向当前页发送表单,method是以何种方式发送表单,有post和get两种,一般选post,如果是get则表单会以url参数方式发送,name是指表单名字,id指该表单的唯一标示,enctype是指表单上传前如何对表单数据进行编码,multipart/form-data是指不对字符编码主要是在表单里有文件上传控件时使用。
第83行p标签是段落标签,即分段;
第84行部门名称的文本输入框,输入控件的标签是input;
type是控件属性,不同属性有不同的功能:text是文本框可以输入文字、file是文件上传控件、button是按钮、submit是提交表单按钮、hide是隐藏控件;
name是该控件的名称,提交表单时程序获取数据时就是用这个名称,可以看下第38行到44行,命名规则建议使用和数据表字段一样的名字,方便辨识;
value是该控件的值,传递到程序里的就是这个值,我这里写了一段代码是用来在修改模式下输出部门名称的,在新增模式下该值为空。
第87到98行是一个选择控件,用来选择部门的上级部门,标签名为select,name为该控件名称;
每个option都是一个选择项,value是该选项的数值,option开闭标签之间是选项描述,最后传递的是value。
option还有一个属性是selected,看名字就知道是选中,如果没有一个选项指定了这个值,则默认第一个为选中状态。因此代码里第一个选项是“无上级部门”,value为0。
在第76行我们将所有的部门数据拉取出来赋值给$class_list,就在这里用了,这个$class_list是用数组存放数据的,所以这里用foreach将记录一条条的读取出来。
第94行是在修改模式条件下,我们希望被修改的记录上级部门名称是选中状态的,因此在循环输出所有部门时,如果上级部门ID和列表部门ID相同时则加上selected,否则为空,赋值给$class_select。然后在输出<option>时就加上这个字符串控制是否要选中。
这里我用了个判断式 (条件)?成立:不成立;等于if(条件){成立}else{不成立}
第102,103行是两个隐藏的输入标签,分别是放置action的值和class_id的值,这可以看到class_id的value是通过前面获取的url参数赋予的。
第105行就是提交按钮。
该页面访问是在浏览器里直接运行,输入你的应用地址加上/class_add.php,执行效果如下:
新增了数据咱们要看看效果呗,就要写个部门列表管理的代码,我们命名为class_manager.php,代码如下:
有部分代码是差不多的,主要解释几个地方吧,
第16行,是获取当前页码参数。
第25行到34行是判断是否要进行删除操作,如果是删除则获取需要删除的部门ID号,删除操作我们不是真正的进行操作,只是将将记录状态由正常变为删除,即1变为0,所以这里执行的其实是更新操作,将status设置成0。
第35行到55行是一个分页的加获取符合条件记录列表的模块。
第38行,要分页肯定先要知道有一共有多少条数据,所以这里是一个计算记录总数的代码,mysql操作函数getVar是返回结果集第一条记录的第一个字段值,sql语句的意思是
select 选择
COUNT(*) 总共多少条记录
from 从
class 名字是class的数据表
where status=1 符合条件为正常的数据
这里的count(*)返回所有记录总数,如果指定某个字段名,则是返回该字段不为空的记录总数。
第40行,计算记录总数除了分页以外还有一个好处就是可以知道到底有没有记录,这里就是判断是否有记录。
第43行,每页显示的条数,因为我这里数据就加了三条,所以设了个2,一般建议10到20。
第45行,如果获取的当前页码是0则表示第一页。
第47行,每一页开始的指针都是不同的,比如每页显示10条的话,第一页是0-9(数据表里记录第一条其实是第0条),第二页是10-19,通过这个代码来确定起始的指针,注意这个指针指记录在数据库里的实际位置,而不是ID号。
第49行,获取记录列表,这里我用了sql左连接查询两张表,主要是为了把记录里的class_fid变成对应的部门名称(class_fid是数字的),其实不推荐使用这种,因为效率很低,不过咱们不用考虑这个。解释下SQL语句,看不懂也没关系照抄吧。
select 选择
A.class_id,A.class_name,表A的序号和部门名
B.class_name as fclass_name 表B的部门名,变量重命名为fclass_name
from 从
class A left join class B 名称为class的表命名为A左连接名称为class的表命名为B
on A.class_fid=B.class_id 两表连接的条件是表A的class_fid等于表B的class_id
where A.status=1 符合条件为A表的状态为正常的数据
order by A.class_id desc 排序按照A表的序号降序排列
limit $from_record,$page_num 从第$from_record获取$page_num条。
第54行,分页函数multi,这个是自己的函数,函数代码在base-class.php里,参数分别是记录总数、每页显示条数、当前页码,还有一个就是列表页的url。
第61行,表格标签,border=1是为了有框框,哈哈。
第62行到64行,表格头,<tr>是行标签,<td>是列标签,就跟xls表格是一样的