当前位置:  编程技术>php
本页文章导读:
    ▪php启动session失败的解决办法      排查步骤: 1、创建一个phpinfo.php,在浏览器中打开。 <?php phpinfo(); ?> 重点关注session部分   2、session.cookie_domain设置了A域名,即session.cookie_domain = A域名结果导致session cookies在B域名失.........
    ▪学习php的防SQL注入函数:mysql_real_escape_string      必须严格过滤用户的数据,来保护网站安全。 PHP中可以使用 mysql_real_escape_string 函数来过滤非法字符。本函数将 string 中的特殊字符转义,并考虑到连接的当前字符集,因此可以安全用于 mysql_.........
    ▪学习使用PDO查询Mysql来避免SQL注入风险      虽然可以用mysql_real_escape_string()函数过滤用户提交的值,但是也有缺陷。 而使用PHP的PDO扩展的 prepare 方法,就可以避免sql injection 风险。 PDO(PHP Data Object) 是PHP5新加入的一个重大功能,因为在P.........

[1]php启动session失败的解决办法
    来源: 互联网  发布时间: 2013-12-24

排查步骤:
1、创建一个phpinfo.php,在浏览器中打开。
<?php
phpinfo();
?>
重点关注session部分
 
2、session.cookie_domain设置了A域名,即session.cookie_domain = A域名结果导致session cookies在B域名失效。
解决办法1:将php.ini中的session.cookie_domain设置为空,即:session.cookie_domain =
解决办法2:session.cookie_domain =设置成你使用的域名
 
3、php.ini中,session.cookie_path设置过于严格。比如设置为:session.cookie_path = /hjaa/也就是说只允许根域名下面的hjaa目录和子目录才能使用session(更确切来讲,如果session.cookie_domain设置了A域名,则表示A域名下的hjaa目录和子目录才允许使用session)
 
解决办法:将php.ini中的session.cookie_path设置为“/”(不含双引号)或者你认为的更加宽松的安全设置,比如: session.cookie_path = /
 
4、php.ini中,将session.cookie_path和session.save_path两者搞混,以为session.cookie_path是表示session临时文件存储的路径。但实际上session.cookie_path是表示session生效的网站域,和服务器的文件权限无关;session.save_path才是设置session临时文件存储的路径。比如将session.cookie_path设置为:session.cookie_path = C:/WINDOWS/TEMP从而引发故障。
 
5、session.save_path设置的目录没有写权限;或者设置不正确(比如设置的文件夹根本不存在)。请注意:如果为空,则表示使用默认的系统临时文件夹路径。windows一般为“%SystemRoot%\TEMP”,unix一般为“/tmp”
解决办法:
(1)、如果session.save_path不留空,请确认该设置值对应的确实是一个文件夹、并且该文件夹存在。如果确实不知道如何设置,请注释此设置、或者改为空值,让php使用默认设置。
(2)、在对应目录中,给予相应用户的写权限比如对于IIS,应给予Internet来宾账户的写权限。
 
6、当session.auto_start = on时,执行 session_start() 将产生新的 session_idsession.auto_start = on 的优点在于,任何时候都不会因忘记执行 session_start() 或 session_start() 在程序里的位置不对,而导致错误缺点在于,如果你使用的是第三方代码,则必须删去其中的全部 session_start() 。否则将不能得到正确的结果
解决办法:
(1)session.auto_start = Off
(2)把程序中的session_start();去掉


    
[2]学习php的防SQL注入函数:mysql_real_escape_string
    来源: 互联网  发布时间: 2013-12-24

必须严格过滤用户的数据,来保护网站安全。

PHP中可以使用 mysql_real_escape_string 函数来过滤非法字符。本函数将 string 中的特殊字符转义,并考虑到连接的当前字符集,因此可以安全用于 mysql_query()()。
mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。下列字符受影响:
\x00
\n
\r
\
'
"
\x1a
如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。
使用下面的这个函数,就可以有效过滤了。
 

代码如下:
function safe($s){ //安全过滤函数
if(get_magic_quotes_gpc()){ $s=stripslashes()($s); }
$s=mysql_real_escape_string($s);
return $s;
}

或者在conn公共连接文件里加入,这样就无需修改代码了:
 

代码如下:
if(get_magic_quotes_gpc()) { $_REQUEST = array_map( 'stripslashes', $_REQUEST); }
$_REQUEST = array_map( 'mysql_real_escape_string', $_REQUEST);

mysql_real_escape_string语法
mysql_real_escape_string(string,connection)
参数 描述
string 必需。规定要转义的字符串。
connection 可选。规定 MySQL 连接。如果未规定,则使用上一个连接。

其实,一般的还可以利用这个函数 addslashes() 进行转义。作用同样为对GET、POST、COOKIE过来的字符串进行转义处理,通常与 magic_quotes_gpc 结合使用。

addslashes  、magic_quotes_gpc、mysql_real_escape_string 三者之间的区别:

1、addslashes  与 mysql_real_escape_string,同样的作用是经过转义后,可直接插入数据库, 国内很多PHP coder是使用addslashes函数防止SQL注入,但是建议大家使用后者转义数据。
举例说明:addslashes的问题在于黑客可以用0xbf27来代替单引号,而addslashes只是将0xbf27修改为0xbf5c27,成为一个有效的多字节字符,其中的0xbf5c仍会被看作是单引号,所以addslashes无法成功拦截。
两者何时用:addslashes也不是毫无用处,它是用于单字节字符串的处理,多字节字符还是用mysql_real_escape_string更加安全。

2、magic_quotes_gpc的说明,在首次客户端运行时,可用第一条的举例,对 magic_quotes_gpc 进行 $_['name'] 判断,可转义处理。

3、 mysql_real_escape_string和 mysql_escape_string 这2个函数的区别:
mysql_real_escape_string 必须在(PHP 5以上、PHP 4 >= 4.3.0)版本的情况下才能使用。否则只能用 mysql_escape_string 。
两者的区别:mysql_real_escape_string 考虑到连接的当前字符集,而 mysql_escape_string 不考虑。

4、实际开发中,正确的逻辑处理:
首先,检查 magic_quotes_gpc 是否配置为自动转义斜线,若为on,应该调用stripslashes去掉$_REQUEST、$_GET,$_POST、$_COOKIE的转义斜线;然后,查询/写入/更新数据至mysql时,再使用mysql_real_escape_string进行字符转义。

参考文档:magic_quotes_gpc、mysql_real_escape_string、addslashes的区别及用法
http://blog.unvs.cn/archives/magic_quotes_gpc-mysql_real_escape_string-addslashes.html


    
[3]学习使用PDO查询Mysql来避免SQL注入风险
    来源: 互联网  发布时间: 2013-12-24

虽然可以用mysql_real_escape_string()函数过滤用户提交的值,但是也有缺陷。
而使用PHP的PDO扩展的 prepare 方法,就可以避免sql injection 风险。

PDO(PHP Data Object) 是PHP5新加入的一个重大功能,因为在PHP 5以前的php4/php3都是一堆的数据库扩展来跟各个数据库的连接和处理,如 php_mysql.dll。 PHP6中也将默认使用PDO的方式连接,mysql扩展将被作为辅助 。官方:http://php.net/manual/en/book.pdo.php

1、PDO配置
使用PDO扩展之前,先要启用这个扩展,PHP.ini中,去掉"extension=php_pdo.dll"前面的";"号,若要连接数据库,还需要去掉与PDO相关的数据库扩展前面的";"号(一般用的是php_pdo_mysql.dll),然后重启Apache服务器即可。
 

代码如下:
extension=php_pdo.dll
extension=php_pdo_mysql.dll

2、PDO连接mysql数据库

代码如下:
$dbh = new PDO("mysql:host=localhost;dbname=db_demo","root","password");
默认不是长连接,若要使用数据库长连接,需要在最后加如下参数:
$dbh = new PDO("mysql:host=localhost;dbname=db_demo","root","password","array(PDO::ATTR_PERSISTENT => true) ");
$dbh = null; //(释放)

3、PDO设置属性
1) PDO有三种错误处理方式:
 PDO::ERrmODE_SILENT不显示错误信息,只设置错误码
 PDO::ERrmODE_WARNING显示警告错
 PDO::ERrmODE_EXCEPTION抛出异常
可通过以下语句来设置错误处理方式为抛出异常
$db->setAttribute(PDO::ATTR_ERrmODE, PDO::ERrmODE_EXCEPTION);
当设置为PDO::ERrmODE_SILENT时可以通过调用errorCode() 或errorInfo()来获得错误信息,当然其他情况下也可以。

2) 因为不同数据库对返回的字段名称大小写处理不同,所以PDO提供了PDO::ATTR_CASE设置项(包括PDO::CASE_LOWER,PDO::CASE_NATURAL,PDO::CASE_UPPER),来确定返回的字段名称的大小写。

3) 通过设置PDO::ATTR_ORACLE_NULLS类型(包括PDO::NULL_NATURAL,PDO::NULL_EmpTY_STRING,PDO::NULL_TO_STRING)来指定数据库返回的NULL值在php中对应的数值。

4、PDO常用方法及其应用
PDO::query() 主要是用于有记录结果返回的操作,特别是SELECT操作
PDO::exec() 主要是针对没有结果集合返回的操作,如INSERT、UPDATE等操作
PDO::prepare() 主要是预处理操作,需要通过$rs->execute()来执行预处理里面的SQL语句,这个方法可以绑定参数,功能比较强大(防止sql注入就靠这个)
PDO::lastInsertId() 返回上次插入操作,主键列类型是自增的最后的自增ID
PDOStatement::fetch() 是用来获取一条记录
PDOStatement::fetchAll() 是获取所有记录集到一个集合
PDOStatement::fetchColumn() 是获取结果指定第一条记录的某个字段,缺省是第一个字段
PDOStatement::rowCount() :主要是用于PDO::query()和PDO::prepare()进行DELETE、INSERT、UPDATE操作影响的结果集,对PDO::exec()方法和SELECT操作无效。

5、PDO操作MYSQL数据库实例
例1:
 

代码如下:
<?php
$pdo = new PDO("mysql:host=localhost;dbname=db_demo","root","");
if($pdo -> exec("insert into db_demo(name,content) values('title','content')")){
echo "插入成功!";
echo $pdo -> lastinsertid();
}
?>
 

 
例2:
 

代码如下:
<?php
$pdo = new PDO("mysql:host=localhost;dbname=db_demo","root","");
$rs = $pdo -> query("select * from test");
$rs->setFetchMode(PDO::FETCH_ASSOC); //关联数组形式
//$rs->setFetchMode(PDO::FETCH_NUM); //数字索引数组形式
while($row = $rs -> fetch()){
print_r($row);
}
?>

例3:
 

代码如下:
<?php
foreach( $db->query( "SELECT * FROM feeds" ) as $row )
{
    print_r( $row );
}
?>

统计有多少行数据:
 

代码如下:
<?php
$sql="select count(*) from test";
$num = $dbh->query($sql)->fetchColumn();
    prepare方式:
$stmt = $dbh->prepare("select * from test");
if ($stmt->execute()) {
while ($row = $stmt->fetch()) {
    print_r($row);
}
}
?>

Prepare参数化查询:
 

代码如下:
<?php
$stmt = $dbh->prepare("select * from test where name = ?");
if ($stmt->execute(array("david"))) {
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    print_r($row);
}
}
?>

如何防止 sql注入

使用PDO访问MySQL数据库时,真正的real prepared statements 默认情况下是不使用的。为了解决这个问题,你必须禁用 prepared statements的仿真效果。下面是使用PDO创建链接的例子:
 

代码如下:
$dbh = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8', 'user', 'pass');
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

setAttribute()这一行是强制性的,它会告诉 PDO 禁用模拟预处理语句,并使用 real parepared statements 。这可以确保SQL语句和相应的值在传递到mysql服务器之前是不会被PHP解析的(禁止了所有可能的恶意SQL注入攻击)。

虽然你可以配置文件中设置字符集的属性(charset=utf8),但是需要格外注意的是,老版本的 PHP( < 5.3.6)在DSN中是忽略字符参数的。

来看一段完整的使用实例:
 

代码如下:
<?php
$dbh = new PDO("mysql:host=localhost; dbname=demo", "user", "pass");
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); //禁用prepared statements的仿真效果
$dbh->exec("set names 'utf8'");
$sql="select * from test where name = ? and password = ?";
$stmt = $dbh->prepare($sql);
$exeres = $stmt->execute(array($testname, $pass));
if ($exeres) {
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    print_r($row);
}
}
$dbh = null;
?>
 

上面这段代码就可以防范sql注入。
当调用 prepare() 时,查询语句已经发送给了数据库服务器,此时只有占位符 ? 发送过去,没有用户提交的数据;当调用到 execute()时,用户提交过来的值才会传送给数据库,他们是分开传送的,两者独立的,SQL攻击者没有一点机会。

需要注意的是以下几种情况,PDO并不能帮助你防范SQL注入:
1、你不能让占位符 ? 代替一组值,如:
SELECT * FROM blog WHERE userid IN ( ? );

2、你不能让占位符代替数据表名或列名,如:
SELECT * FROM blog ORDER BY ?;

3、你不能让占位符 ? 代替任何其他SQL语法,如:
SELECT EXTRACT( ? FROM datetime_column) AS variable_datetime_element FROM blog;


    
最新技术文章:
▪PHP函数microtime()时间戳的定义与用法
▪PHP单一入口之apache配置内容
▪PHP数组排序方法总结(收藏)
▪php数组排序方法大全(脚本学堂整理奉献)
▪php数组排序的几个函数(附实例)
▪php二维数组排序(实例)
▪php根据键值对二维数组排序的小例子
▪php验证码(附截图)
▪php数组长度的获取方法(三个实例)
▪php获取数组长度的方法举例
▪判断php数组维度(php数组长度)的方法
▪php获取图片的exif信息的示例代码
▪PHP 数组key长度对性能的影响实例分析
▪php函数指定默认值的方法示例
▪php提交表单到当前页面、提交表单后页面重定...
▪php四舍五入的三种实现方法
▪php获得数组长度(元素个数)的方法
▪php日期函数的简单示例代码
▪php数学函数的简单示例代码
▪php字符串函数的简单示例代码
▪php文件下载代码(多浏览器兼容、支持中文文...
▪php实现文件下载、支持中文文件名的示例代码...
▪php文件下载(防止中文文件名乱码)的示例代码
▪解决PHP文件下载时中文文件名乱码的问题
▪php数组去重(一维、二维数组去重)的简单示例
▪php小数点后取两位的三种实现方法
▪php Redis 队列服务的简单示例
▪PHP导出excel时数字变为科学计数的解决方法
▪PHP数组根据值获取Key的简单示例
▪php数组去重的函数代码示例
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,