qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

如何用Jmeter做压力测试

Jmeter是一个性能测试工具,同loadrunner类似,他功能较多,我们常用的功能是用jmeter模拟多浏览器对网站做压力测试。
  下载jmeter地址 :http://jakarta.apache.org/site/downloads/downloads_jmeter.cgi
  我们一般的网站,在进入业务功能前先需登录,然后才能访问业务功能。下面介绍如何用jmeter登录系统再对主业务做压力测试。
  1. 运行jmeter
  2. 左边树将出现测试计划、工作台两根节点。
  3. 选择测试计划,按右键-》添加-》threads(users)线程组
  线程组能设置以多少个线程并发做压力测试。
  在”循环次数”设置不选择永远,循环次数设置1。
  4. 现在先介绍如何设置登录http请求,选择线程组,右键――添加――》sampler-―》http 请求。
  http请求即模仿浏览器的访问。
  在“服务器名称或ip”设置127.0.0.1,端口号设置:8080,“方法”设置post,路径设置网站登录的地址,如“/exam/operatorAction”。
  登录需传入用户、密码。在“同请求一起发送参数”列表中添加参数。参数值根据web应用设置。如login_user=0001;login_password=1;actFlag=login
  5. 登录成功后,网站一般将跳入主页面。在jmap中可做判断,判断是否登录后按预想进入主页面(此步骤也可不设)。选择4中的“http请求“,右键――》添加――》断言――》响应断言。“Apply to”设置Main smaple only;“要测试的响应字段”设置“url样本”;“模式匹配规则”设置“包括”,“要测试的模式”增加页面跳转到的主页面,如:“studentMain.jsp”
  6. 一般网站登录后,在tomcat中生成了session,之后访问其他页面将无需再次登录,前提是浏览器需支持cookie。在jmap中也同样,如要继续访问其他页面,还需做下面关键的设置。
  选择“线程组”――》右键――》添加――》配置元件――》Http cookie管理器。加了此步骤后,http请求将具备cookie功能,即登录成功后访问其他页面将不会跳转到登录页面重新登录。
  7. 对目标页面反复压力测试。
  7.1 如何使被测页面反复访问达到测压效果。选“线程组”―》右键――》逻辑控制器――》循环控制器。循环次数中选择“永远”。
  7.2 选择刚加的“循环控制器”,右键――》添加――》sampler-―》http 请求,按4步骤设置ip、端口,http请求方法为“get”,路径为被压力测试的url,如:“exam/business/studentExam.action.StudentExamAction?action=goIntoMockExam”。
  按上面的设置后,已完成配置,可做压力测试。只需点菜单“运行”――》启动,即运行压力测试。
  8. jmeter提供了许多压力结果查看工具。是压力测试时非常好的分析工具。下面几种查看工具可有选择的添加。
  8.1 察看结果树。他记录每次请求发送数据、响应返回数据。选择“线程组”――》右键――》添加――》察看结果树。
  8.2 用表格查看结果。可查看每次请求的响应时间等。选择“线程组”――》右键――》添加――》用表格查看结果。
  8.3 Summary Report。可查看平均响应时间、最长响应时间等。

posted @ 2014-04-25 10:06 顺其自然EVO 阅读(3713) | 评论 (0)编辑 收藏

高效的软件研发团队结构

 在前面为各位读者介绍了谁是最佳软件质量责任人——软件开发者。并给大家介绍了因此会给组织和个人带来的价值和好处。但是这里还有一个关键问题还需要解决,否则把软件质量责任人转换为软件开发者的这个改革就会变的无法实施。
  什么问题呢?——软件开发者增加了质量保障的职责,可他有足够的资源来完成这个职责吗? 如果只是简单地给软件开发者增加职责,又没有新增资源来支持他的新职责,那么这个改变不但不会得到好的效果,还会遭到开发者的更强烈的反对,他们更愿意回到过去的那种状态。因此为了让开发人员能更好的保障质量,就需要帮助开发人员提升工作效率,辅助他保障质量,而不是让他一个人孤军奋战。当然如果你的团队都是精英开发者,个人战斗力极强,孤军奋战也没有问题,那么就无需为他们提供开发效率提升和质量保障方面的支撑。
  那么软件开发者增加了质量保障的职责后,需要增加哪些对应的资源以支撑他们可以在质量保障与功能实现的职责间获得平衡。
  1: 教给开发者高效的快速验证软件质量风险的测试方法
  2: 减少开发者自验证测试的时间成本和复杂度
  3: 提供帮助开发者提高开发效率的开发工具和开发框架
  4: 让开发者的编译速度更快减少编译等待时间
  5: 通过有效的方法提高开发人员评审需求和设计的效率
  6: 减少开发人员分析定位bug的时间
  当你的开发人员能得到以上部分资源的支持时,他们才能挤出时间来思考如何能在设计和开发阶段保障自己输出的质量。
  可是公司中哪有资源来支持开发人员来提高工作效率呢?这里我们可以参考软件工程发展最前沿的美国公司的实践。在当前硅谷最先进软件生产力的公司——谷歌,他们的组织结构中有一个叫EP(Engine Productive)的团队,这个团队与广告技术团队、搜索算法团队、架构设计团队、性能团队的定位一样,是谷歌的长线建设的领域技术团队。该团队的成员有:
  测试开发工程师、工具开发工程师、测试工程师组成。测试工程师工作的目标变为了:帮助产品快速地达到质量目标,而不是作为质量保障的主体。
  EP团队除了对软件质量的检查测试提供测试技术支持和测试资源外,还负责帮助开发人员提升工作效率,优化一切可以提升工作效率的工作环节。例如:开发人员更有效的测试,更合理的测试投入,减少与业务实现无关的工作耗时,帮他们更好地做好开发阶段的质量保障工作。在谷歌有些团队能达到10:1的开发测试人员比,除了这位测试人员能力超群外,开发人员的专业能力和开发人员的质量保障目标都是关键的决定因素。如果只有一位超级测试人员,没有开发人员作为质量责任主体和专业技能优秀的开发人员,那么10:1的配置下这位超级测试人员则会被各种软件问题铺天盖地淹没掉。
  如上图所示大多数的研发团队模式是旧模式,开发团队只关注进度,测试团队只关注质量。于是测试团队规模越来越大,产品的进度总是与质量目标矛盾重重。如果应用新模式,则赋予开发团队更大的权利和责任,进度和质量都是由开发团队说了算,当开发团队因缺乏资源完成进度和质量目标时,开发团队可以通过EP团队的临时支援协助达成目标。
  开发团队与EP团队之间的合作模式,还应该是开发团队有需求时拉上EP团队来共同工作。而不应该是EP团队去推动开发团队,开发团队被动使用EP团队资源来共同工作。如果开发团队被动的被EP团队推动去提升工作效率和工作质量,则很可能会同时伤害到开发团队和EP团队的士气,EP团队去推动开发团队会受到很多阻力,感觉不到自我存在的价值,士气受影响。开发团队则被动的被服务,觉得自己的工作节奏受到了影响,影响自己的工作进度,心里也是不舒服的,影响士气。

posted @ 2014-04-25 10:04 顺其自然EVO 阅读(300) | 评论 (0)编辑 收藏

软件测试策略之单元测试

 软件测试策略
  测试过程按4个步骤进行,即单元测试,组装测试,确认测试和系统测试
  开始是单元测试,集中对用源代码实现的每一个程序单元进行测试,检查各个程序模块是否正确的实现了规定的功能。
  组装测试是把已经测试过的模块组装起来,主要对与设计相关的软件体系结构的构造进行测试。
  确认测试则是要检查已实现的软件是否满足了需求规格说明书中确定了的各种需求,以及软件配置是否完全,正确。
  系统测试,是把已经经过确认的软件纳入实际运行环境中,与其他的系统成份组合在一起进行测试。
  单元测试(Unit Testing)
  单元测试又称模块测试,是针对软件设计的最小单位---程序模块,进行正确性检验的测试工作。其目的在于发现各模块内部可能存在的各种差错。
  单元测试需要从程序的内部结构出发设计测试用例。多个模块可以平行的独立进行单元测试。
  1、单元测试的内容
  在单元测试时,测试者需要依据详细设计说明书和源程序清单,了解该模块的I/O条件和模块的逻辑结构,主要采用白盒测试的测试用例,辅之以黑盒测试的测试用例,使之对任何合理的输入和不合理的输入,都能鉴别和响应。
  (1)模块接口测试
  在单元测试的开始,应对通过被测模块的数据流进行测试。测试项目包括:
  u  调用本模块的输入参数是否正确
  u  本模块调用子模块时输入给子模块的参数是否正确
  u  全局量的定义在各模块中是否一致
  在做内外存交换时要考虑:
  u  文件属性是否正确
  u  OPEN与CLOSE语句是否正确
  u  缓冲区容量与记录长度是否匹配
  u  在进行读写操作前是否打开了文件
  u  在街上文件处理时是否关闭了文件
  u  正文书写/输入错误
  u  I/O错误是否检查并做了处理
(2)局部数据结构测试
  u  不正确或不一致的数据类型说明
  u  使用尚未赋值或尚未初始化的变量
  u  错误的初始值或错误的缺省值
  u  变量名拼写错或书写错
  u  不一致的数据类型
  u  全局数据对模块的影响
  (3)路径测试
  u  选择适当的测试用例,对模块中重要的执行路径进行测试
  u  应当设计测试用例查找由于错误的计算,不正确的比较或不正常的控制流而导致的错误
  u  对基本执行路径和循环进行测试可以发现大量的路径错误
  (4)错误处理测试
  u  出错的描述是否难以理解
  u  出错的描述是否能够对错误定位
  u  显示的错误与实际的错误是否相符
  u  对错误条件的处理正确与否
  u  在对错误进行处理之前,错误条件是否已经引起系统的干预等
  (5)边界测试
  u  注意数据流,控制流中刚好等于,大于或小于确定的比较值时出错的可能性。对这些地方要仔细的选择测试用例,认真的加以测试。
  u  如果对模块运行时间有要求的话,还要专门进行关键路径测试,以确定最坏情况下和平均意义下影响模块运行时间的因素。
  2、  单元测试的步骤
  模块并不是一个独立的程序,在考虑测试模块时,同时要考虑它和外界的联系,用一些辅助模块与被测模块相联系的其他模块。
  u  驱动模块(driver)
  u  桩模块(stub)-----存根模块
  n  如果一个模块要完成多种功能,可以将这个模块看成由几个小程序组成。必须对其中每个小程序先进行单元测试要做的工作,对关键模块还要做性能测试。
  n  对支持某些标准规程的程序,更要着手进行互联测试。有人把这种情况特别成为模块测试,以区别单元测试。

posted @ 2014-04-25 10:03 顺其自然EVO 阅读(296) | 评论 (0)编辑 收藏

性能测试脚本分析学习

  今天继续学习了查询入库_入库完全收货脚本录制。
  前提:入库收货页面存在大数据量,是几十万条数据,不输入查询条件默认是查询前部数据。
  操作:不输入查询条件,点击查询,默认查询全部数据
  存在问题:1.录制完成查询和收货后,保存脚本会有报错
  2.在tree目录下查找request,没看到查询response信息
  3.脚本分析出现很多重复的request
  原因:大数据查询,需等待一段时间,即后台刷新会出现request发出重复信息
  由于大数据,response信息过大,loadrunner无法重载出新response查找不到信息,同时保存报错。
  正确录制:
  1.输入OrderNO ,点击查询,操作收货。
  2.从request脚本分析<Operation>query<Operation> 计算查询操作发出请求,同时可以看response返回来的信息。
  3.查看完所有request可以看到,收货的request信息在查询中可以去调用。
  4.即在查询结果去做关联,在收货可以调用。
  5.由于查询条件OrderNO是输入的每次值会不一样,即需要做Script做参数化,导入数据库的值。
  6.每次回放脚本看是否成功,在tree目录下replay去查看response返回来的值是否正确,或者登陆系统去查看数据
  总结:参数化或者关联都是为request做更加真实的模仿,所以脚本那些变量需要参数化,第一步一定要从request去分析脚本,从<Operation>方法<Operation>去理解对应到系统的是做什么操作

posted @ 2014-04-25 09:58 顺其自然EVO 阅读(186) | 评论 (0)编辑 收藏

Robotium测试用例执行顺序及批处理方式

一、控制测试用例的执行顺序
  采用TestSuit方式来控制每条Case的运行顺序
  Demo如下
public static Test suite() {
TestSuite suite = new TestSuite();
//$JUnit-BEGIN$
suite.addTestSuite(CopyOfTestApk.class);
//$JUnit-END$
return suite;
}
  二、bat批处理方式启动Robotium脚本
  单个启动
  am instrument -w com.testcalculator/android.test.InstrumentationTestRunner
  启动Test Suit
  Am instrument -e class com.testcalculator.AllTests -w com.testcalculator/android.test.InstrumentationTestRunner
  Java中启动
public  void callChosenTest(){
Runtime run = Runtime.getRuntime();
try {
//Process p = run.exec("am instrument -w com.testcalculator/android.test.InstrumentationTestRunner");///执行全部的测试案例
Process p = run.exec("am instrument -e class com.testcalculator.AllTests -w com.testcalculator/android.test.InstrumentationTestRunner");
//执行一个测试案例
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 命令行启动
  1.运行所有的测试用例
  举个栗子:运行测试工程下的所有用例
  1adb shell am instrument -w com.taobao.taobao.test/android.test.InstrumentationTestRunner
  2.运行单个测试类或某个TestSuite
  举个栗子:运行测试类com.taobao.taobao.test.TestRegister
  1adb shell am instrument -e class com.taobao.taobao.test.TestRegister -w com.taobao.taobao.test/android.test.InstrumentationTestRunner
  3.运行某个测试类里面的某个测试方法
  举个栗子:运行com.taobao.taobao.test.TestRegister中的测试方法testRegister
  adb shell am instrument -e class com.taobao.taobao.test.TestRegister#testRegister -w com.taobao.taobao.test/android.test.InstrumentationTestRunner
  4.运行两个不同的测试类或类中的方法
  举个栗子:运行com.taobao.taobao.test.TestLogin和com.taobao.taobao.test.TestRegister类中的方法testRegister
1adb shell am instrument -e class com.taobao.taobao.test.TestLogin,com.taobao.taobao.test.TestRegister#testRegister  -w com.taobao.taobao.test/android.test.InstrumentationTestRunner
Runtime run = Runtime.getRuntime();
try {
//Process p = run.exec("am instrument -w com.testcalculator/android.test.InstrumentationTestRunner");///执行全部的测试案例
Process p = run.exec("am instrument -e class com.testcalculator.AllTests -w com.testcalculator/android.test.InstrumentationTestRunner");
//执行一个测试案例
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

posted @ 2014-04-25 09:55 顺其自然EVO 阅读(2107) | 评论 (0)编辑 收藏

sqlyog导入数据库脚本报错

  前两天将客户的数据库备份成sql文件,sql文件大小61M.发给同事之后。同事说导入的时候一直报错。导出方式和发送了几次,还是报错。我还以为我的导出有错或者网络原因。可是在我的电脑上测试还是出现这样的问题。
  最后的解决办法是:
  #直接在sqlyog里面执行,修改这两个变量的值:
  set global max_allowed_packet=10000000;
  set global net_buffer_length=10000;
  执行完这两句后,再次导入sql文件问题得到解决。下面是执行完这两句之后的截图:

posted @ 2014-04-24 10:29 顺其自然EVO 阅读(443) | 评论 (0)编辑 收藏

Java中super的使用

  一、super调用超类构造函数
  super(parameter-list);
  parameter-list指定超类中构造函数所需的任何形参,super()必须是在子类构造函数中执行的第一个语句。超类定义的任何形式的构造函数都可以被super()调用,被执行的构造函数就是与实参相匹配的那一个。
  当存在多重继承时,super总是引用最靠近的超类的构造函数。例如:C类继承B类,B类继承A类,则C类的构造函数中使用super,引用B类的构造函数。
  如果不使用super(),那么就会执行每个超类的默认(无形参)构造函数。
  例如:
<span style="font-size:14px;">public class test {
public static void main(String [] args){
new Teacher("one", 62);
new Teacher("two", 180);
new Teacher("three", 65, 188);
}
}
class Human {
static private float weight;
static private int height;
Human(float weight){
Human.weight = weight;
System.out.println(Human.weight);
}
Human(int height){
Human.height = height;
System.out.println(Human.height);
}
Human(float weight, int height){
Human.weight = weight;
Human.height = height;
System.out.println(Human.weight + " " + Human.height);
}
}
class Teacher extends Human {
static private String s;
Teacher(String s, float weight){
super(weight);
Teacher.s = s;
System.out.println(Teacher.s);
}
Teacher(String s, int height){
super(height);
Teacher.s = s;
System.out.println(Teacher.s);
}
Teacher(String s, float weight, int height){
super(weight, height);
Teacher.s = s;
System.out.println(Teacher.s);
}
}
</span>
  结果:
  62
  one
  180
  two
  65.0 188
  three
 二、super访问超类的成员
  例如:
<span style="font-size:14px;">public class test {
public static void main(String [] args){
new Teacher("three", 65, 188);
}
}
class Human {
static public float weight;
static public int height;
}
class Teacher extends Human {
static private String s;
Teacher(String s, float weight, int height){
super.weight = weight;
super.height = height;
Teacher.s = s;
System.out.println(super.weight);
System.out.println(super.height);
System.out.println(Teacher.s);
}
}</span>
  结果:
  65.0
  188
  three
  三、super和this的区别
  1)super(参数):调用基类中的某一个构造函数(应该为构造函数中的第一条语句);this(参数):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句);
  2)super引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名    super.成员函数据名(实参);this代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名);
  3)调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错;super()和this()类似,区别是,super()从子类中调用父类的构造方法,this()在同一类内调用其它方法;
  4)super()和this()均需放在构造方法内第一行;
  5)尽管可以用this调用一个构造器,但却不能调用两个;
  6)this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过;
  7)this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块;
  8)从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。

posted @ 2014-04-24 10:28 顺其自然EVO 阅读(205) | 评论 (0)编辑 收藏

Java线程池的工作原理与实现

  简单介绍
  创建线程有两种方式:继承Thread或实现Runnable。Thread实现了Runnable接口,提供了一个空的run()方法,所以不论是继承Thread还是实现Runnable,都要有自己的run()方法。
  一个线程创建后就存在,调用start()方法就开始运行(执行run()方法),调用wait进入等待或调用sleep进入休眠期,顺利运行完毕或休眠被中断或运行过程中出现异常而退出。
  wait和sleep比较:
  sleep方法有:sleep(long millis),sleep(long millis, long nanos),调用sleep方法后,当前线程进入休眠期,暂停执行,但该线程继续拥有监视资源的所有权。到达休眠时间后线程将继续执行,直到完成。若在休眠期另一线程中断该线程,则该线程退出。
  wait方法有:wait(),wait(long timeout),wait(long timeout, long nanos),调用wait方法后,该线程放弃监视资源的所有权进入等待状态;
  wait():等待有其它的线程调用notify()或notifyAll()进入调度状态,与其它线程共同争夺监视。wait()相当于wait(0),wait(0, 0)。
  wait(long timeout):当其它线程调用notify()或notifyAll(),或时间到达timeout亳秒,或有其它某线程中断该线程,则该线程进入调度状态。
  wait(long timeout, long nanos):相当于wait(1000000*timeout + nanos),只不过时间单位为纳秒。
  线程池的作用:
  线程池作用就是限制系统中执行线程的数量。
  根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了;否则进入等待队列。
  为什么要用线程池:
  减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务
  可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)
  线程池:
  多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。
  假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。
  如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。
  一个线程池包括以下四个基本组成部分:
  1、线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
  2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
  3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
  4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。
  线程池技术正是关注如何缩短或调整T1,T3时间的技术,从而提高服务器程序性能的。它把T1,T3分别安排在服务器程序的启动和结束的时间段或者一些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1,T3的开销了。
  线程池不仅调整T1,T3产生的时间段,而且它还显著减少了创建线程的数目,看一个例子:
  假设一个服务器一天要处理50000个请求,并且每个请求需要一个单独的线程完成。在线程池中,线程数一般是固定的,所以产生线程总数不会超过线程池中线程的数目,而如果服务器不利用线程池来处理这些请求则线程总数为50000。一般线程池大小是远小于50000。所以利用线程池的服务器程序不会为了创建50000而在处理请求时浪费时间,从而提高效率。

posted @ 2014-04-24 10:27 顺其自然EVO 阅读(1091) | 评论 (0)编辑 收藏

LoadRunner参数化使用mysql数据源

使用LoadRunner中的参数化,数据源来自mysql数据表。
  使用mysql数据源之前,要先安装mysql驱动。http://dev.mysql.com/downloads/connector/odbc/,这里以Connector/ODBC 5.2.6为例。
  安装过程中如果遇到类似于ANSI问题,要将Windows>>system32>>msvcr100_clr0400.dll复制,改名为msvcr100.dll
  安装即可成功。可以在控制面板中,Administrative Tools >>Data Sources (ODBC)找到刚才安装的驱动。
  然后在User DSN中点Add,选择刚添加的mysql驱动。
  Data Source Name 和 Description中,随意填写。server中填写服务器的ip,我用的本机的数据库,所以填写为127.0.0.1
  User name 和Password就不用说了吧。Database是选择要使用的数据库,点test测试一下。好了, 连接成功。
  回到LoadRunner中,在参数化窗口中点Data Wizard...按钮。
  选中Specify SQL statement manually.
  在machine Data Source中选中数据源
  点Create...按钮,在SQL语句中输入适当的语句。数据导入成功。

posted @ 2014-04-24 10:26 顺其自然EVO 阅读(2200) | 评论 (0)编辑 收藏

Thinkphp防止SQL注入

防止SQL注入
  对于WEB应用来说,SQL注入攻击无疑是首要防范的安全问题,系统底层对于数据安全方面本身进行了很多的处理和相应的防范机制,例如:
$User = M("User"); // 实例化User对象
$User->find($_GET["id"]);
  即便用户输入了一些恶意的id参数,系统也会强制转换成整型,避免恶意注入。这是因为,系统会对数据进行强制的数据类型检测,并且对数据来源进行数据格式转换。而且,对于字符串类型的数据,ThinkPHP都会进行escape_string处理(real_escape_string,mysql_escape_string)。
  通常的安全隐患在于你的查询条件使用了字符串参数,然后其中一些变量又依赖由客户端的用户输入,要有效的防止SQL注入问题,我们建议:
  查询条件尽量使用数组方式,这是更为安全的方式;
  如果不得已必须使用字符串查询条件,使用预处理机制(3.1版本新增特性);
  开启数据字段类型验证,可以对数值数据类型做强制转换;(3.1版本开始已经强制进行字段类型验证了)
  使用自动验证和自动完成机制进行针对应用的自定

posted @ 2014-04-24 10:26 顺其自然EVO 阅读(168) | 评论 (0)编辑 收藏

仅列出标题
共394页: First 上一页 120 121 122 123 124 125 126 127 128 下一页 Last 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜