php文件防删改,PHP实现增删改查以及防SQL注入

最近项目调研时,需要在集成板子上做个配置的网页,板子上装的是linux系统,配置信息在一个SQLite数据库中,经过讨论大家决定用PHP做这个网页。由于项目组没一个会PHP的,所以安排我调研下写个Demo,经过几天的研究终于完成了Demo的调研(调研过程主要参考网络,具体开发就交给月底入职的小弟去做了,哈哈,有个小弟真好),特此记录(根据我调研的顺序展开)。

项目截图:

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

1.搭建环境         首先当然是搭建环境了,我选择的是phpstudy(下载和安装可

参考,完全傻瓜式),编译器选择的是免费的Notepad++(只因为免费而选用,实际效果比记事本好点而已)。至此你可以开发第一个Hello World了。语法可

参考。发布也很简单,只要把php文件放到网站目录下就行了(如安装教程中,目录就是D:\WWW)。网站的端口号可以打开phpStudy主界面,点击其他选项菜单,点击myHomePage,就能看到端口号啦。

2.PHP从SQLite中读取信息         代码如下:

if ($db = sqlite_open('GateWay.db')) {

$sql = "select * from ComInfo";

$res = sqlite_unbuffered_query($db, $sql);

echo "

echo "

comIdcomNamebaudparitydataBitstopBit";

echo"

";

while($item = sqlite_fetch_array($res, SQLITE_ASSOC))

{

echo "

";

echo "

".$item["comId"]."";

echo "

".$item["comName"]."";

echo "

".$item["baud"]."";

echo "

".$item["parity"]."";

echo "

".$item["dataBit"]."";

echo "

".$item["stopBit"]."";

}

echo "

";

sqlite_close($db);

}

3通过Ajax获得信息         作为一个网站,现在很少能看到每次提交刷新整个页面的网站了。下面是通过Ajax请求获得数据(这个跟html中类似,这边用的是jQuery中封装的Ajax):在页面上有一个id为fullDataDiv的DIV用来装获取的数据,代码如下:

//js代码

var data={ opType:"ShowAllComInfo" };

$.post("ComInfoServer.php", data, function (result) {

$("#fullDataDiv").html(result);

});

//ComInfoServer.php页面的代码

$opType = $_POST["opType"];

switch($opType)

{

case "ShowAllComInfo":

{

if ($db = sqlite_open('GateWay.db')) {

$sql = "select * from ComInfo";

$res = sqlite_unbuffered_query($db, $sql);

echo "

echo "

comIdcomNamebaudparitydataBitstopBit";

echo"

";

while($item = sqlite_fetch_array($res, SQLITE_ASSOC))

{

echo "

";

echo "

".$item["comId"]."";

echo "

".$item["comName"]."";

echo "

".$item["baud"]."";

echo "

".$item["parity"]."";

echo "

".$item["dataBit"]."";

echo "

".$item["stopBit"]."";

}

echo "

";

sqlite_close($db);

}

}

break;

}

4.新建记录         接着是新建记录,本质跟Ajax查询类似,代码如下:

//js代码

var comName = $('#tbComName').val();

var baud = $("select#selBaud option:selected").text();

var parity = $("select#selParity option:selected").text();

var dataBit = $("select#selDataBit option:selected").text();

var stopBit = $("select#selStopBit option:selected").text();

var data={opType:"AddComInfo",comName: comName, baud: baud,parity:parity,dataBit:dataBit,stopBit:stopBit};

$.post("ComInfoServer.php", data, function (result) {

alert("Add Success!");

});

//ComInfoServer.php页面的代码

$comName =$_POST["comName"];

$baud = $_POST["baud"];

$parity = $_POST["parity"];

$dataBit = $_POST["dataBit"];

$stopBit = $_POST["stopBit"];

if ($db = sqlite_open($dbName)) {

$sql= "insert into ComInfo values(null,'".$comName."', '".$baud."','".$parity."', '".$dataBit."', '".$stopBit."')";

sqlite_query($db, $sql);

sqlite_close($db);

}

5.删除记录         然后就是删除记录,比新增还简单,只需要传一个ID就行,ID在当前行的第一列(var comInfoid = $(this).parents("tr").find('td:first').text();),代码跟新增类似,就不贴了。

6.编辑记录         最后是编辑,为了调研页面跳转,我把编辑放在另一个页面,页面传值直接放在url中,EditComInfoServer.php页面中放了一个隐藏控件保存ComInfoid的值,在页面加载完毕之后根据id向服务端请求完整的数据。代码如下:

//ComInfoMain.php的js代码

$(".edit").click(function(){

var comInfoid = $(this).parents("tr").find('td:first').text();

window.location= "ComInfoServer.php?ComInfoid="+comInfoid;

});

//EditComInfoServer.php

//隐藏控件

//js代码

$(function () {

var URL = "ComInfoHandler.ashx";

var data={ComInfoid: $("#tbComInfoid").val(),opType:"EditInit" };

$.post(URL, data, function (result) {

var info=eval("(" + result + ")");

comName =info.comName;

baud = info.baud;

parity = info.parity;

dataBit = info.dataBit;

stopBit = info.stopBit;

$("#tbComName").val(comName);

$("#selBaud option[value='"+baud+"']").attr("selected", true);

$("#selParity option[value='"+parity+"']").attr("selected", true);

$("#selDataBit option[value='"+dataBit+"']").attr("selected", true);

$("#selStopBit option[value='"+stopBit+"']").attr("selected", true);

});

});

7.PHP+Sqlite的防注入以及错误友好提示         至此初步的增删改查都实现了,但只是实现,根本没考虑安全性。主要有三个方面:如果输入数据库的完整路径,数据库都被下载下来了;或者在comName里精心填入一些字符串就能实现SQL注入;另外出错了,提示也很不友好,直接把程序信息都泄露出来了。

7.1防止数据库被下载         对于数据库被下载(这个问题在Access和SQLite中都有),可以不让其直接访问,具体配置是在网站的根目录新建一个文件名为.htaccess的文件(直接新建不了,可以另存为该文件,另外注意的是这个文件与PHP的版本有关,我用的是Apache+PHP5.3),用记事本打开写入内容如下:

Deny from all

        其他的设置在最新的版本中已经都是默认设置了,这样,数据库文件就不会被访问下载了。

7.2防止SQL注入         对于注入攻击,从两方面下手,前台验证输入的内容(过滤一些注入的关键字),后台再进行二次验证。根据我们实际的业务,我在前台只限制了长度,后台对传入的字符串进行加密之后存到数据库中的,读取的时候再解密。其中解密的几个方法

来自这里。这样做法其实对存储有浪费的,经过测试,加密后的字符串长度是原来的两到三倍,图省事我把comName的字段类型改成了text。在实际操作时还遇到了截取字符串乱码的问题,原因是substr在遇到汉字时会遇到编码问题,因此采用mb_substr方法。代码如下:

//新增或更新时

$postComName=$_POST["comName"];

if(strlen($postComName)>10)

{

$postComName=mb_substr($postComName,0,10,'utf-8');

}

$comName =passport_encrypt($postComName,$key);

//读取时解密

$comName=passport_decrypt($item["comName"],$key);

7.3URL重写         在注入攻击的问题上还可以通过重写url隐藏网站的技术,当然这不能从本质上防SQL注入,只是提高注入的难度而已。在刚刚的.htaccess加入如下代码:

RewriteEngine on

RewriteRule main.html ComInfoMain.php

RewriteRule ComInfoHandler.ashx ComInfoServer.php

RewriteRule ^edit([0-9]+)\.html$ EditComInfoServer.php?ComInfoid=$1

        这样访问main.html就自动解析为ComInfoMain.php,其中第三个规则是用正则表达式实现,例如edit23.html就解析成EditComInfoServer.php?ComInfoid=23。这个调查了大半天,只因为网上的大多都是以讹传讹(或许是版本的原因吧)。当然了,还有一个原因就是配置文件的苛刻要求。在调查期间删除了一个"看似多余"空格导致Apache启动不起来了,元凶如下:

0818b9ca8b590ca3270a3433284dd417.png         这个空格删除了就启动不了Apache,而且没有什么有效的提示,真坑爹。

7.4错误友好提示         最后就是错误友好提示了,打开phpStudy主界面,点击其他选项菜单,点击打开配置文件选httpd.conf找到ErrorDocument 404,将其前面的#去除,在后面加上error的页面,本例中设置是ErrorDocument 404 /error.html,这里表示error.html放在网站根目录下。

至此全部完成,Demo很简单,希望能对刚学PHP的读者有些帮助,欢迎阅读、讨论、转载,转载请保留原文链接。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/556449.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c# python 相互调用_【GhPython】Python如何使用“委托”和lambda表达式

【版权声明】| 作者:月之眼| 首发于大水牛参数化设计平台| 如需转载请联系作者| 如果觉得文章不错,欢迎分享 函数作为参数传入 在python中函数是能作为参数输入函数的。这个有点类似于C#中的委托,将一个函数封装到一个委托对象里,…

chimerge算法matlab实现,有监督的卡方分箱算法

实现代码import numpy as npimport pandas as pdfrom collections import Counterdef chimerge(data, attr, label, max_intervals):distinct_vals sorted(set(data[attr])) # Sort the distinct valueslabels sorted(set(data[label])) # Get all possible labelsempty_coun…

金士顿u盘真假软件_简洁轻巧 金士顿DT80 Type-C高速闪存盘评测

从都市的高端会议到普通的日常娱乐,USB高速闪存应用于我们生产生活的方方面面。它小巧便携,稳定可靠的特点吸引了无数人去使用,同时为我们提供了诸多便利。闪存盘也就是日常生活中经常提到的U盘。大多数人对于U盘的印象是老式的USB Micro接口…

php阴影效果,如何使用css3实现文字的单阴影效果和多重阴影效果(

使用css3实现文本阴影效果的原理实现阴影效果主要是用text-shadow属性,根据W3C标准,如果我们想要在IE下兼容CSS3的阴影属性可以使用ie.css3-htc,不过按照标准InternetExplorer9以及更早版本的浏览器暂时不支持text-shadow属性。最基本的语法为…

promise链式调用_这一次,彻底弄懂 Promise

Promise 必须为以下三种状态之一:等待态(Pending)、执行态(Fulfilled)和拒绝态(Rejected)。一旦Promise 被 resolve 或 reject,不能再迁移至其他任何状态(即状态 immutable)。基本过程:初始化 Promise 状态(pending)执行 then(..) 注册回调处…

visual studio 判断dropdownlist选的是什么_心理测试:五个小蓝人,你选哪个?测你是不是一个容易追求的人...

下面这张图片里,有五个小蓝人,你觉得自己会是里面的哪一个?A. 站在家里的窗户边B. 站在河边C. 坐在屋顶D. 站在树上E. 骑着鸟飞在空中测试结果选A的你容易追求指数20%。你是一个温柔细腻的人。在别人的眼里,你是一个很贴心的人。在…

java中为何输出框会无限输出,MyBatis启动时控制台无限输出日志的原因及解决办法...

你是否遇到过下面的情况,控制台无限的输出下面的日志:Logging initialized using ‘class org.apache.ibatis.logging.log4j.Log4jImpl adapter.Logging initialized using ‘class org.apache.ibatis.logging.log4j.Log4jImpl adapter.Logging initiali…

基于注解SpringAOP,AfterReturning,Before,Around__springboot工程 @Around 简单的使用__SpringBoot:AOP 自定义注解实现日志管理

基于注解SpringAOP,AfterReturning,Before,Around AOP(Aspect Oriented Programming),即面向切面编程(也叫面向方面编程,面向方法编程)。其主要作用是,在不修…

流浪地球开机动画包zip_【文娱热点】流浪地球2定档2023大年初一;迪士尼计划裁员32000人...

剧集、综艺任嘉伦、白鹿《长安如故》开机11月26日,根据小说《一生一世美人骨》古代篇改编的剧集《长安如故》开机,两位主演任嘉伦和白鹿继现代篇《一生一世》之后再演古代篇,俩人穿着棉服、梳着古装发髻现身开机仪式,心情非常好。…

matlab读气象数据,中国气象数据网

“中国气象科学数据共享服务网”的气象卫星资料与国内其他气象卫星资料发布平台的最大不同之处,在于卫星数据资源内容不同且时间序列相当完整。而且,(1)数据获取更便捷。在线获取数据无需等待邮件通知,无数据下载量限制。共享卫星资源是公益性…

spring中自定义注解(annotation)与AOP中获取注解___使用aspectj的@Around注解实现用户操作和操作结果日志

spring中自定义注解(annotation)与AOP中获取注解 一、自定义注解(annotation) 自定义注解的作用:在反射中获取注解,以取得注解修饰的类、方法或属性的相关解释。 package me.lichunlong.spring.annotation;import java.lang.annotation.Documented; …

python 编译器pyc_有没有办法知道哪个Python版本.pyc文件被编译?

Is there any way to know by which Python version the .pyc file was compiled? 解决方案 You can get the magic number of your Python as follows: $ python -V Python 2.6.2 # python >>> import imp >>> imp.get_magic().encode(hex) d1f20d0a To ge…

Spring AOP——Spring 中面向切面编程

前面两篇文章记录了 Spring IOC 的相关知识,本文记录 Spring 中的另一特性 AOP 相关知识。 部分参考资料: 《Spring实战(第4版)》 《轻量级 JavaEE 企业应用实战(第四版)》 Spring 官方文档 W3CSchool Spri…

python getchar,Linux C编程学习:getchar()和getch()

getchar函数名: getchar功 能: 从stdin流中读字符用 法: int getchar(void);注解:getchar有一个int型的返回值,当程序调用getchar时程序就等着用户按键,用户输入的字符被存放在键盘缓冲区中直到用户按回车为止(回车字符也放在缓冲区中)。当用…

python 折线图中文乱码_彻底解决 Python画图中文乱码问题--Pyplotz组件

1 源起 自从开始学习Python,就非常喜欢用来画图。一直没有需求画要中文显示信息的图,所以没有配置Python中文的环境。由于昨天就需要画几十个形式相同,只是数据不同的图,并且需要显示中文信息。如果用Excel画图会很浪费时间&#…

SpringBoot的AOP是默认开启的,不需要加注解@EnableAspectJAutoProxy____听说SpringAOP 有坑?那就来踩一踩

Aspect Component public class CustomerServiceInterceptor {Before("execution(public * org.example.aop.demo..*.*(..))")public void doBefore() {System.out.println("do some important things before...");} }另外SpringBoot默认是cglib动态代理&a…

mysql 开启远程访问_QxOrm 访问 MySQL

在前面的 QxOrm 章节中,我们已经介绍了对本地数据库的操作,现在是时候介绍对远程数据库的访问了,那么就以最常用的 MySQL 为例吧!在开始之前,首先要安装 MySQL。如果条件允许,建议将其安装在 Linux 系统上&…

当泛型遇到重载

当泛型遇到了重载,好戏,就发生了。 请看下面代码: 问题:代码能正确编译吗? 这个题目是一个考察泛型的题目。java里面,泛型实际上是“伪泛型”,并不像C#那样是实际上的泛型。 IDE会提示我们下…

redis查询所有key命令_三歪推荐:Redis常见的面试题

本文公众号来源:科技缪缪作者:科技缪缪本文已收录至我的GitHub说说Redis基本数据类型有哪些吧字符串:redis没有直接使用C语言传统的字符串表示,而是自己实现的叫做简单动态字符串SDS的抽象类型。C语言的字符串不记录自身的长度信息…

springboot系列——redisTemplate和stringRedisTemplate对比、redisTemplate几种序列化方式比较

文章目录一、redisTemplate和stringRedisTemplate对比1、StringRedisTemplate2、RedisTemplate二、redisTemplate序列化方式比较1、性能测试对比2、性能总结3、方案一、考虑效率和可读性,牺牲部分空间4、方案二、空间敏感,忽略可读性和效率影响5、使用示…