预览模式: 普通 | 列表

PHP提交email表单防注入

<html>
<body>
<?php
function spamcheck($field)
  {
  //filter_var() sanitizes the e-mail
  //address using FILTER_SANITIZE_EMAIL
  $field=filter_var($field, FILTER_SANITIZE_EMAIL);
 
  //filter_var() validates the e-mail
  //address using FILTER_VALIDATE_EMAIL
  if(filter_var($field, FILTER_VALIDATE_EMAIL))
    {
    return TRUE;
    }
  else
    {
    return FALSE;
    }
  }

if (isset($_REQUEST['email']))
  {//if "email" is filled out, proceed

  //check if the email address is invalid
  $mailcheck = spamcheck($_REQUEST['email']);
  if ($mailcheck==FALSE)
    {
    echo "Invalid input";
    }
  else
    {//send email
    $email = $_REQUEST['email'] ;
    $subject = $_REQUEST['subject'] ;
    $message = $_REQUEST['message'] ;
    mail("someone@example.com", "Subject: $subject",
    $message, "From: $email" );
    echo "Thank you for using our mail form";
    }
  }
else
  {//if "email" is not filled out, display the form
  echo "<form method='post' action='mailform.php'>
  Email: <input name='email' type='text' /><br />
  Subject: <input name='subject' type='text' /><br />
  Message:<br />
  <textarea name='message' rows='15' cols='40'>
  </textarea><br />
  <input type='submit' />
  </form>";
  }
?>

</body>
</html>

在上面的代码中,我们使用了 PHP 过滤器来对输入进行验证:

  • FILTER_SANITIZE_EMAIL 从字符串中删除电子邮件的非法字符
  • FILTER_VALIDATE_EMAIL 验证电子邮件地址

Tags: php

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 2722

  1.Minimize HTTP Requests 减少HTTP请求
图片、css、script、flash等等这些都会增加http请求数,减少这些元素的数量就能减少响应时间。把多个JS、CSS在可能的情况下写进一个文件,页面里直接写入图片也是不好的做法,应该写进CSS里,利用 CSS sprites 将小图拼合后利用background来定位。

  2.Use a Content Delivery Network 利用CDN技术
CDN 确实是好东西,8过服务器提供商的这项服务一般是要收费的,我以前买的国内空间是有这个的但是我当时根本不知道啥用,现在没了。。。

  3.Add an Expires or a Cache-Control Header 设置头文件过期或者静态缓存
浏览器会用缓存来减少http请求数来加快页面加载的时间,如果页面头部加一个很长的过期时间,浏览器就会一直缓存页面里的元素。不过这样如果页面里的东西变动的话就要改名字了,否则用户端不会主动刷新,看自己衡量了~ 这项可以通过修改.htaccess文件来实现。

  4.Gzip Components Gzip压缩
Gzip格式是一种很普遍的压缩技术,几乎所有的浏览器都有解压Gzip格式的能力,而且它可以压缩的比例非常大,一般压缩率为85%。压缩没压缩,可以到 这里 做下测试。

查看更多...

分类:业界文摘 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 2008

PHP中遍历目录的两种方法

PHP中两种遍历某个目录下的子目录及文件的方法,遍历时主要是采用递归的算法,读某个目录下面的内容时,如果是目录,则递归遍历此目录,如果是文件,则将结果追加到数组中,同时数组用全局变量,定义在函数的外面,这样便于数组一直将结果递增起来。

方法一

$dir = "e:/myphp/research/mailapi";
$dirs = array();

function scan_dir($dir) {
    global $dirs;
    if (!is_dir($dir)) return false;

    if ($dh = opendir($dir)) {
        while (($file = readdir($dh)) !== false) {
            if ($file[0] == '.') continue;
            $fullpath = "$dir/$file";
            $dirs[] = $fullpath;
            if (is_dir($fullpath)) scan_dir($fullpath);           
        }
        closedir($dh);
    }

查看更多...

Tags: php

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 2035

PHP优化

 软件开发中程序的性能永远都占据着比较重要的地位,下面是我上网上收集的几篇PHP代码优化相关的文章,尤其是最后一篇写得好,希望对PHPer一族有些帮助,其实绝大部分都好理解,只时平时工作中如果不注意的话可能会忽略一些问题,习惯成自然,平时在工作中形成了习惯,自然会注意这些问题。

优化PHP代码的40条建议,http://www.yeeyan.com/articles/view/davidkoree/4409

10条PHP编程习惯助你找工作,http://www.yeeyan.com/articles/view/38585/11529

PHP程序61条面向对象分析设计的经验原则,http://www.phpx.com/viewarticle.php?id=148255

A HOWTO on Optimizing PHP,http://phplens.com/lens/php-book/optimizing-debugging-php.php

Tags: php

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1795

PHP中几个小问题

 1.定界符中的变量解析问题

$data = array('name' => 'caihf', 'province' => 'hubei');
echo <<<END
My name is: $data['name'], i come from $data['province']
END
/*
Parse error: parse error, expecting `T_STRING' or `T_VARIABLE' or `T_NUM_STRING' in E:myphp esearch est.php on line 4
*/

echo <<<END
My name is: {$data['name']}, i come from {$data['province']}
END
就不会报错了


 

定界符在PHP手册中的说明
另一种给字符串定界的方法使用定界符语法(“<<<”)。应该在 <<< 之后提供一个标识符,然后是字符串,然后是同样的标识符结束字符串。

查看更多...

Tags: php

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1939

关于PHP中的文件包含方法

 做PHP开发时避免不了文件包含的问题,当文件不在同一个目录下面时文件如何包含是有些技巧及学问的,现在大致总结一下,希望对大家有所帮助。

几个测试文件的文件名及路径大致如下:

e:\myphp\research\path\path.php

e:\myphp\research\path\path1.php

查看更多...

Tags: php

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 2009

PHP开发中值得注意的几个问题

注意的问题一:字符串是否自动转义的问题
a.用户从页面中输入的内容或从URL地址中传入的参数的字符串转义问题
http://www.abc.com/advice.php?email=caihuafeng@gmail.com&osval=winxp&brval=ie70&question=i%20come%20from%20baidu,test%20%22%20and%20%27&indexUrl=http://www.265.com/&im=caihf666@hotmail.com

如果php.ini中magic_quotes_gpc的设置为Off,sql是由变量动态生成的,这些变量可能含有特殊字符,但是你在进行sql查询前没有将其中的特殊字符(如"、'及\等)进行转义,则执行mysql时会报类似如下的错误。
magic_quotes_gpc = On
; 是否对输入的GET/POST/Cookie数据使用自动字符串转义( '  "  \  NULL )。
; 这里的设置将自动影响 $_GEST $_POST $_COOKIE 数组的值。
; 若将本指令与magic_quotes_sybase指令同时打开,则仅将单引号(')转义为(''),
; 其它特殊字符将不被转义,即( "  \  NULL )将保持原样!!
; 建议关闭此特性,并使用自定义的过滤函数。

作用范围是:WEB客户服务端;
作用时间:请求开始是,例如当脚本运行时.

参数question的值为i come from baidu,test " and '
MySQL Query Error: Insert INTO client_feedback (`os`,`browse`,`index`,`email`,`question`,`im`,`time`,`ip`) VALUES ('winxp','ie70','http://www.265.com/','caihuafeng@gmail.com','i come from baidu,test " and '','caihf666@hotmail.com','1258536394','127.0.0.1') Error Info:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'caihf666@hotmail.com','1258536394','127.0.0.1')' at line 1

此时应该对有可能出现特殊字符的变量进行处理,如定义如下的一个函数,则处理完了以后,不管变量中是否有特殊字符,不管magic_quotes_runtime的值是什么,则执行sql语句时不会报这种类型的错误了。
function strAddslashes($value)
{
    if ($value == '') return false;
   
    if (is_array($value)) {
        $value = array_map('strAddslashes', $value) :
    } else {
        if (!get_magic_quotes_gpc()) $value = addslashes($value);
    }

    return $value;
}

b.从数据库或文件中读取数据的字符串转义问题
magic_quotes_runtime = Off
; 是否对运行时从外部资源产生的数据使用自动字符串转义( '  "  \  NULL )。
; 若打开本指令,则大多数函数从外部资源(数据库,文本文件等)返回数据都将被转义。
; 例如:用SQL查询得到的数据,用exec()函数得到的数据,等等
; 若将本指令与magic_quotes_sybase指令同时打开,则仅将单引号(')转义为(''),
; 其它特殊字符将不被转义,即( "  \  NULL )将保持原样!!
; 建议关闭此特性,并视具体情况使用自定义的过滤函数。

作用范围:从文件中读取的数据或执行exec()的结果或是从SQL查询中得到的;
作用时间:每次当脚本访问运行状态中产生的数据.

假如magic_quotes_runtime的设置为on,某些变量需要从某个文件中读取,从其中读取的字符串含有特别字符串(如"、'及\等),此时如果不处理,则页面上这些特殊字符分别会显示\"、\'及\\,不是我们想要看到的结果,因此此时可以用下面定义的函数strStripslashes处理一下就可以了。
function strStripslashes($value)
{
    if ($value == '') return false;
   
    if (is_array($value)) {
        $value = array_map('strStripslashes', $value) :
    } else {
        if (!get_magic_quotes_runtime()) $value = stripslashes($value);
    }

    return $value;
}

测试一
文件file1.txt内容如下:
Test the special character " and ' and \

如果采用读取文件内容的方式读取文件(如用file_get_contents函数读取文件),则内容中的特殊字符会自动转义
文件file.php内容如下:
<?php
//refer http://doc.bsdlover.cn/html/php/2009/0522/2344.html
define("NEWLINE", "<br />\n");
echo "This is file file.php" . NEWLINE;
echo 'get_magic_quotes_runtime:' . get_magic_quotes_runtime() . NEWLINE;
//include_once(dirname(__FILE__) . '/./file1.txt');
$str = file_get_contents('file1.txt');
echo "str:$str" . NEWLINE;
echo "abcd\"ef" . NEWLINE;
?>

执行file.php输出内容如下:
This is file file.php
get_magic_quotes_runtime:1
str:Test the special character \" and \' and \\
abcd"ef

测试二
文件file1.txt内容如下:
Test the special character " and ' and \

如果采用直接包含文件的方式加载文件,则内容中的特殊字符不会自动转义,所以一定要注意
文件file.php内容如下:
<?php
//refer http://doc.bsdlover.cn/html/php/2009/0522/2344.html
define("NEWLINE", "<br />\n");
echo "This is file file.php" . NEWLINE;
echo 'get_magic_quotes_runtime:' . get_magic_quotes_runtime() . NEWLINE;
include_once(dirname(__FILE__) . '/./file1.txt');
echo NEWLINE;
//$str = file_get_contents('file1.txt');
//echo "str:$str" . NEWLINE;
echo "abcd\"ef" . NEWLINE;
?>

执行file.php输出内容如下:
This is file file.php
get_magic_quotes_runtime:1
Test the special character " and ' and \
abcd"ef

测试三
文件file1.php的内容如下:
<?php
$str = "Test the special character \" and ' and \\";
?>

与上面的测试二加载文本文件file1.txt文件一样,用包含文件的方式加载php文件file1.php,内容中的特殊字符也不会自动转义。
顺便说一下,页面中的字符串abcd"ef输出时"也不会自动转义
文件file.php内容如下:
<?php
//refer http://doc.bsdlover.cn/html/php/2009/0522/2344.html
define("NEWLINE", "<br />\n");
echo "This is file file.php" . NEWLINE;
echo 'get_magic_quotes_runtime:' . get_magic_quotes_runtime() . NEWLINE;
include_once(dirname(__FILE__) . '/./file1.php');
//$str = file_get_contents('file1.txt');
echo "str:$str" . NEWLINE;
echo "abcd\"ef" . NEWLINE;
?>

执行file.php输出内容如下:
This is file file.php
get_magic_quotes_runtime:1
str:Test the special character " and ' and \
abcd"ef

注意问题二:php.ini中几个重要的配置
php的错误级别
error_reporting  =  E_ALL & ~E_NOTICE

display_errors最好设置为On,否则程序报错的时候都不知道错在哪里
; To output errors to STDERR with CGI/CLI:              
;display_errors = "stderr"
;
; Default
;
display_errors = On

是否将上一次的错误或警告信息保存在变量$php_errormsg中,如果网站上线后有一些敏感信息不想让用户知道,则可以将track_errors设为on,将display_errors设为Off,然后将此变量写到日志文件,以方便调试bug。
; Store the last error/warning message in $php_errormsg (boolean).
track_errors = Off

error_log =
; 将错误日志记录到哪个文件中。该文件必须对Web服务器用户可写。
; syslog 表示记录到系统日志中(NT下的事件日志, Unix下的syslog(3))
; 如果此处未设置任何值,则错误将被记录到Web服务器的错误日志中。

log_errors = Off
; 是否在日志文件里记录错误,具体在哪里记录取决于error_log指令。
; 强烈建议你在最终发布的web站点时使用日志记录错误而不是直接输出,
; 这样可以让你既知道那里出了问题,又不会暴露敏感信息。

register_globals最好设置为Off,这样更加安全一点
; You should do your best to write your scripts so that they do not require
; register_globals to be on;  Using form variables as globals can easily lead
; to possible security problems, if the code is not very well thought of.
register_globals = Off

如果你需要php作为脚本运行,同时又需要往php的命令行里面传递参数,则需要将register_argc_argc设置为On
; This directive tells PHP whether to declare the argv&argc variables (that
; would contain the GET information).  If you don't use these variables, you
; should turn it off for increased performance.
register_argc_argv = Off

如果你想通过PHP上传超大的文件,以下几项配置可能都需要修改
;Maximum size of POST data that PHP will accept.
post_max_size = 100M
     
; Maximum allowed size for uploaded files.
upload_max_filesize = 100M
     
max_execution_time = 1800     ; Maximum execution time of each script, in seconds
max_input_time = 1800    ; Maximum amount of time each script may spend parsing request data
memory_limit = 128M      ; Maximum amount of memory a script may consume (128MB)

除非提高程序的移植性,建议用<?php ?>,这样不管short_open_tag是On还是Off,则均不会出现无法解析php程序的问题。
short_open_tag = On
; 是否允许使用"<? ?>"短标识。否则必须使用"<?php ?>"长标识。
; 除非你的php程序仅在受控环境下运行,且只供自己使用,否则请不要使用短标记。
; 如果要和XML结合使用PHP,可以选择关闭此选项以方便直接嵌入"<?xml ... ?>",
; 不然你必须用PHP来输出:<? echo '<?xml version="1.0"'; ?>
; 本指令也会影响到缩写形式"<?=",它和"<? echo"等价,要使用它也必须打开短标记。

关于php.ini的配置选项可以看http://cn2.php.net/manual/en/ini.list.php

You can use the ini_set() function to set a directive's  value in your scripts provided the "CHANGEABLE" attribute in the above chart is PHP_INI_USER or PHP_INI_ALL.
php.ini中是PHP_INI_USER及PHP_INI_ALL级别的选项可以通过ini_set函数在php脚本中手动的设置

PHP_INI_* 常量的定义

常量 值 含义
PHP_INI_USER 1 配置选项可在用户的 PHP 脚本或 Windows 注册表中设置
PHP_INI_PERDIR 2 配置选项可在 php.ini, .htaccess 或 httpd.conf 中设置
PHP_INI_SYSTEM 4 配置选项可在 php.ini or httpd.conf 中设置
PHP_INI_ALL 7 配置选项可在各处设置

注意问题三:关于空值的判断
如果判断一个变量是否为空且认为0不为空,则最好的判断方法是用if ($value == '') return false;
如果用if (empty($value)) 来判断的话,则当$value的值为0的时候,此条件返回true,而又假如0又不是我们想要过滤的值,则此时程序会出现bug,我以前出现过两三次这样的错误,也在这里顺便总结一下。

$a !== $b 非全等 TRUE,如果 $a 不等于 $b,或者它们的类型不同。(PHP 4 引进)
$val = "0";
var_dump($val !== 0);
var_dump((int)$val !== 0);
var_dump($val != 0);

分别输出如下:
bool(true) bool(false) bool(false)

$val = 0;
var_dump($val !== 0);
var_dump((int)$val !== 0);
var_dump($val != 0);

分别输出如下:
bool(false) bool(false) bool(false)

empty在PHP手册中的说明
如果 var 是非空或非零的值,则 empty() 返回 FALSE。换句话说,""、0、"0"、NULL、FALSE、array()、var $var; 以及没有任何属性的对象都将被认为是空的,如果 var 为空,则返回 TRUE。

isset在PHP手册中的说明
如果 var 存在则返回 TRUE,否则返回 FALSE。

如果已经使用 unset() 释放了一个变量之后,它将不再是 isset()。若使用 isset() 测试一个被设置成 NULL 的变量,将返回 FALSE。同时要注意的是一个 NULL 字节("\0")并不等同于 PHP 的 NULL 常数。

<?php
$var = '';

// 结果为 TRUE,所以后边的文本将被打印出来。
if (isset($var)) {
    print "This var is set set so I will print.";
}

// 在后边的例子中,我们将使用 var_dump 输出 isset() 的返回值。

$a = "test";
$b = "anothertest";

var_dump( isset($a) );      // TRUE
var_dump( isset ($a, $b) ); // TRUE

unset ($a);

var_dump( isset ($a) );     // FALSE
var_dump( isset ($a, $b) ); // FALSE

$foo = NULL;
var_dump( isset ($foo) );   // FALSE
?>  

这对于数组中的元素也同样有效:
<?php
$a = array ('test' => 1, 'hello' => NULL);

var_dump( isset ($a['test']) );            // TRUE
var_dump( isset ($a['foo']) );             // FALSE
var_dump( isset ($a['hello']) );           // FALSE

// 键 'hello' 的值等于 NULL,所以被认为是未置值的。
// 如果想检测 NULL 键值,可以试试下边的方法。
var_dump( array_key_exists('hello', $a) ); // TRUE
?> 
 

Tags: php

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1553

PHP开发中值得注意的几个问题(二)

1.关于时区的问题
; Defines the default timezone used by the date functions
;date.timezone =
 
 从php5.1.0开始,php.ini里加入了date.timezone这个选项,默认情况下是关闭的
也就是显示的时间(无论用什么php命令)都是格林威治标准时间
和我们的时间(北京时间)差了正好8个小时,有以下3中方法可以恢复正常的时间。

1,最简单的方法就是不要用php5.1以上的版本
2,如果一定要用,而且不能修改php.ini,则需要在关于时间的初始化的语句的
上面加上 date_default_timezone_set (XXX);
cp无此问题
3,一劳永逸,仅限能修改php.ini。打开php.ini查找date.timezone 去掉前面的分号
= 后面加XXX,重启http服务(如apache2或iis等)即可

也可以自己写个函数来解决此问题
/**
 * Format date and time
 *
 * @param string $format time format
 * @param string $time   timestamp
 *
 * @return string
 */
function getDatetime($format = "Y-m-d H:i:s", $time = "") {
    setTimezone();
    if (empty($format)) $format = "Y-m-d H:i:s";
    if (empty($time)) $time = time();
    return date($format, $time);
}
   
function setTimezone($sTimeZone = "PRC") {
    if (function_exists('date_default_timezone_set')) {
        date_default_timezone_set($sTimeZone); //该函数为PHP5.1内置,这里设置为香港时间。
    }
}

2.关于空字符串的测试
$str = '';
var_dump($str === '');
var_dump($str == '');
var_dump($str !== '');
var_dump($str != '');

bool(true) bool(true) bool(false) bool(false)

3.php.ini中几个配置
disable_classes =
;SYS
; 该指令接受一个用逗号分隔的类名列表,以禁用特定的类。

disable_functions =
;SYS
; 该指令接受一个用逗号分隔的函数名列表,以禁用特定的函数。

enable_dl = On
;SYS
; 是否允许使用dl()函数。dl()函数仅在将PHP作为apache模块安装时才有效。
; 禁用dl()函数主要是出于安全考虑,因为它可以绕过open_basedir指令的限制。
; 在安全模式下始终禁用dl()函数,而不管此处如何设置。
; PHP6中删除了该指令,相当于设为Off。

expose_php = On
;SYS
; 是否暴露PHP被安装在服务器上的事实(在http头中加上其签名)。
; 它不会有安全上的直接威胁,但它使得客户端知道服务器上安装了PHP。

open_basedir =
;SYS
; 将PHP允许操作的所有文件(包括文件自身)都限制在此组目录列表下。
; 当一个脚本试图打开一个指定目录树之外的文件时,将遭到拒绝。
; 所有的符号连接都会被解析,所以不可能通过符号连接来避开此限制。
; 特殊值'.'指定了存放该脚本的目录将被当做基准目录。
; 但这有些危险,因为脚本的工作目录可以轻易被chdir()改变。
; 对于共享服务器,在httpd.conf中灵活设置该指令将变得非常有用。
; 在Windows中用分号分隔目录,UNIX系统中用冒号分隔目录。
; 作为Apache模块时,父目录中的open_basedir路径将自动被继承。
; 指定的限制实际上是一个前缀,而非一个目录名,
; 也就是说"/dir/incl"将允许访问"/dir/include"和"/dir/incls",
; 如果您希望将访问控制在一个指定的目录,那么请在结尾加上一个斜线。
; 默认是允许打开所有文件。

output_buffering = 0
; 输出缓冲区大小(字节)。建议值为4096~8192。
; 输出缓冲允许你甚至在输出正文内容之后再发送HTTP头(包括cookies)。
; 其代价是输出层减慢一点点速度。
; 设置输出缓冲可以减少写入,有时还能减少网络数据包的发送。
; 这个参数的实际收益很大程度上取决于你使用的是什么Web服务器以及什么样的脚本。

Tags: php

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1474

PHP开发中值得注意的几个问题(三)

1.md5
当内容为空时,md5空内容后也是有值的
md5(''):d41d8cd98f00b204e9800998ecf8427e

2.关于特殊字符转换
$str = "<strong>abcd\"</strong>";
$str = htmlspecialchars($str);
echo $str;
write_file('debug.log', $str);
?>
<textarea name="text" rows="5" cols="30"><?php echo $str;?></textarea>

页面输出如下:
<strong>abce"</strong>
当然textarea里面的内容也是<strong>abce"</strong>
查看页面的源代码如下(为了防止页面乱码或错乱,所以需要将内容转换一下[如将<转换为&lt;,>转换为&gt;],提交之后还需要转换一下[如将&lt;转换为<,&gt;转换为>],得到原始的数据,如<strong>abcd\"</strong>):
&lt;strong&gt;abce&quot;&lt;/strong&gt;<textarea name="text" rows="5" cols="30">&lt;strong&gt;abce&quot;&lt;/strong&gt;</textarea>

将变量$str的值保存在文件debug.log中,内容如下
&lt;strong&gt;abce&quot;&lt;/strong&gt;

3.关于addslashes
$data = array("a\"", "b\"", "c\"");
//addslashes($data, 1);
print_r($data);
如果没有上述addslashes那行代码,则输出Array ( [0] => a" [1] => b" [2] => c" )
否则输出Array ( [0] => a\" [1] => b\" [2] => c\" )

4.不同编码的汉字在urlencode后的内容是不同的
a.如果字符串内容是数字或字母,则utf8编码以后内容不变
 

b.
/*
关于中文urlencode测试
下面的例子输出如下:
basketball(gb2312):%C0%BA%C7%F2
basketball(utf-8):%E7%AF%AE%E7%90%83

在六间房输入关键字篮球时的url地址,参数k的值是utf8编码的汉字urlencode以后的内容
http://6.cn/search.php?k=%E7%AF%AE%E7%90%83&t=v

通过此例可以说明一个问题,即不同编码的字符经过urlencode处理以后的结果是不相同的,进行测试时此文件内容本身的编码为utf8
*/
$str = '篮球';
echo "basketball(gb2312):" . urlencode($str) . NEWLINE;
echo "basketball(utf-8):" . urlencode(iconv('gb2312', 'utf-8', $str)) . NEWLINE;

5.php文件上传中的错误代码

上传文件的时候要注意一下这些错误代码
错误信息说明

从 PHP 4.2.0 开始,PHP 将随文件信息数组一起返回一个对应的错误代码。该代码可以在文件上传时生成的文件数组中的 error 字段中被找到,也就是 $_FILES['userfile']['error']。

UPLOAD_ERR_OK

其值为 0,没有错误发生,文件上传成功。
UPLOAD_ERR_INI_SIZE

其值为 1,上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值。
UPLOAD_ERR_FORM_SIZE

其值为 2,上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。
UPLOAD_ERR_PARTIAL

其值为 3,文件只有部分被上传。
UPLOAD_ERR_NO_FILE

其值为 4,没有文件被上传。
UPLOAD_ERR_NO_TMP_DIR

其值为 6,找不到临时文件夹。PHP 4.3.10 和 PHP 5.0.3 引进。
UPLOAD_ERR_CANT_WRITE

其值为 7,文件写入失败。PHP 5.1.0 引进。

    注: 以上值在 PHP 4.3.0 之后变成了 PHP 常量。

6.关于函数的定义
switch ($act) {
    case 'log':
        get_log();
        break;
}

if ($act == 'log') {
    function get_log() {
        //do something
    }
}
会报函数get_log没有定义的错误

if ($act == 'log') {
    function get_log() {
        //do something
    }
}
改为
function get_log() {
    //do something
}
就不报错了,暂时不知道为什么会这样?

7.关于error_reporting

在公共的包含文件中最好有error_reporting(E_ALL & ~E_NOTICE),这样不管php.ini的配置是怎样的,都不会报E_NOTICE级别的错误。

8.XSS攻击判断
可以参考我以前写的,简单的写了一下

9.SQL注入
SQL注入用通俗一点的说法理解就是,你的程序中的sql语句是动态组成的,其中部分内容接收用户输入的参数,如果你没有对用户输入的参数进行过滤及校验,则有可能利用你程序的漏洞获取你数据库中的一些信息,对公司造成损失。

可以用mysql_escape_string或mysql_real_escape_string过滤一下用户输入的参数,这样就相对比较安全了。

mysql_escape_string
*******************************************

查看更多...

Tags: php

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1780

PHP中文件上传时的注意事项

php中如果不修改php.ini,默认最大只能上传2M的文件,如果要上传超过2M的文件,则必须修改php.ini的相关配置。

如果要上传的文件有点大,如8M左右,则大概需要修改以下的几项配置。

post_max_size,file_uploads,upload_max_filesize,max_execution_time,max_input_time,memory_limit

-------------------------------------------
post_max_size = 10M
; 允许的POST数据最大字节长度。此设定也影响到文件上传。
; 如果POST数据超出限制,那么$_POST和$_FILES将会为空。
; 要上传大文件,该值必须大于upload_max_filesize指令的值。
; 如果启用了内存限制,那么该值应当小于memory_limit指令的值。

可修改范围: PHP_INI_PERDIR(配置选项可在 php.ini, .htaccess 或 httpd.conf 中设置)
-------------------------------------------

-------------------------------------------
file_uploads = On
;SYS
; 是否允许HTTP文件上传。
; 参见upload_max_filesize, upload_tmp_dir, post_max_size指令

可修改范围:PHP_INI_SYSTEM(配置选项可在 php.ini or httpd.conf 中设置)
-------------------------------------------

-------------------------------------------
upload_max_filesize = 10M
; 允许上传的文件的最大尺寸。

可修改范围: PHP_INI_PERDIR(配置选项可在 php.ini, .htaccess 或 httpd.conf 中设置)
-------------------------------------------

-------------------------------------------
max_execution_time = 300
; 每个脚本最大允许执行时间(秒),0 表示没有限制。
; 这个参数有助于阻止劣质脚本无休止的占用服务器资源。
; 该指令仅影响脚本本身的运行时间,任何其它花费在脚本运行之外的时间,
; 如用system()/sleep()函数的使用、数据库查询、文件上传等,都不包括在内。
; 在安全模式下,你不能用ini_set()在运行时改变这个设置。
;
; 可以通过函数set_time_limit(0)来设置程序不超时。
You can not change this setting with ini_set() when running in 安全模式. The only workaround is to turn off safe mode or by changing the time limit in the php.ini.

可修改范围: PHP_INI_ALL(配置选项可在各处设置)
-------------------------------------------

-------------------------------------------
max_input_time = -1
; 每个脚本解析输入数据(POST, GET, upload)的最大允许时间(秒)。
; -1 表示不限制。
max_input_time integer
This sets the maximum time in seconds a script is allowed to receive input data, like POST, GET and file uploads.

可修改范围: PHP_INI_PERDIR(配置选项可在各处设置)
-------------------------------------------

-------------------------------------------
memory_limit = 128M
; 一个脚本所能够申请到的最大内存字节数(可以使用K和M作为单位)。
; 这有助于防止劣质脚本消耗完服务器上的所有内存。
; 要能够使用该指令必须在编译时使用"--enable-memory-limit"配置选项。
; 如果要取消内存限制,则必须将其设为 -1 。
; 设置了该指令后,memory_get_usage()函数将变为可用。

可修改范围: PHP_INI_ALL(配置选项可在各处设置)
-------------------------------------------

=============================================
安装模式的设置说明
safe_mode = Off
;SYS
; 是否启用安全模式。
; 打开时,PHP将检查当前脚本的拥有者是否和被操作的文件的拥有者相同,
; 相同则允许操作,不同则拒绝操作。

修改完以上几项配置以后,一般需要将Web服务器重启以便修改生效(如果php是用fastcgi方式运行,则只需要重启php-fpm即可)

Tags: php

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1794

1.如果要用fopen打开远程文件,则此时最好检查一下php.ini中的配置选项allow_url_fopen,如果为on则可以打开,否则不能打开
if (ini_get('allow_url_fopen')) {
    //可以打开远程文件
} else {
    //不能打开远程文件
}

; Whether to allow the treatment of URLs (like http:// or ftp://) as files.
allow_url_fopen = On

2.如果要包含远程文件,则此时最好检查一下php.ini中的配置选项allow_url_include,如果为on则可以包含,否则不能包含
; Whether to allow include/require to open URLs (like http:// or ftp://) as files.
allow_url_include = Off

做个简单的测试,此时allow_url_include的值为Off
测试前配置一下hosts文件,这样可以在一台电脑上面进行模拟测试
192.168.1.101 www.test1.com
192.168.1.102 www.test2.com

path.php文件内容为:
<?php
echo "This is file path.php<br />\n";
include("http://www.test2.com/research/path/path.php");
?>

path1.php文件内容为:
<?php
echo "This is file path1.php in root directory\n";
?>
执行http://www.test1.com/research/path/path.php,输出如下
This is file path.php

Warning: include() [function.include]: URL file-access is disabled in the server configuration in E:\myphp\research\path\path.php on line 3

Warning: include(http://www.test2.com/research/path/path.php) [function.include]: failed to open stream: no suitable wrapper could be found in E:\myphp\research\path\path.php on line 3

Warning: include() [function.include]: Failed opening 'http://www.test2.com/research/path/path.php' for inclusion (include_path='.;C:\php5\pear') in E:\myphp\research\path\path.php on line 3

将php.ini中的allow_url_include改为On,重新启动web服务器,再次执行http://www.test1.com/research/path/path.php,输出如下:
This is file path.php
This is file path1.php in root directory
将allow_url_include设为On以后,就可以包含远程文件了,并且包含的是远程文件执行的结果。

3.测试文件包含的返回值
a.包含本地文件并获取被包含文件的返回值
path.php
<?php
echo "This is file path.php<br />\n";
$name = include 'path1.php';
echo "name: $name<br />\n";
?>

path1.php
<?php
$name = 'caihuafeng';
return $name; //注意这儿是return $name;
?>
运行path.php,输出如下:
This is file path.php
name: caihuafeng
说明path1.php的返回值成功包含在path.php中了

==============================
b.用readfile函数直接读取远程文件的执行结果
php手册中的说明
安全警告
远程文件可能会经远程服务器处理(根据文件后缀以及远程服务器是否在运行 PHP 而定),但必须产生出一个合法的 PHP 脚本,因为其将被本地服务器处理。如果来自远程服务器的文件应该在远端运行而只输出结果,那用 readfile() 函数更好。另外还要格外小心以确保远程的脚本产生出合法并且是所需的代码。

int readfile ( string filename [, bool use_include_path [, resource context]] )
读入一个文件并写入到输出缓冲。

测试如下:
path.php
<?php
echo "This is file path.php<br />\n";
readfile('http://www.test2.com/research/path/path1.php');
?>
readfile打开远程文件时allow_url_fopen必须设置为On

path1.php
<?php
$name = 'caihuafeng';
echo $name; //因为readfile是要读取文件的执行结果,所以这儿要输出
?>
输出如下:
This is file path.php
caihuafeng

c.包含远程文件

php手册中的说明
处理返回值:可以在被包括的文件中使用 return() 语句来终止该文件中程序的执行并返回调用它的脚本。同样也可以从被包含的文件中返回值。可以像普通函数一样获得 include 调用的返回值。不过这在包含远程文件时却不行,除非远程文件的输出具有合法的 PHP 开始和结束标记(如同任何本地文件一样)。可以在标记内定义所需的变量,该变量在文件被包含的位置之后就可用了。

用这种方式有点麻烦,就是被包含文件的输出必须是佥的php开始和结束标记(echo '<?php $name = "caihuafeng ' . $a . '"; ?>';),就像下面path1.php的输出一样。
同时可以向被包含的文件中传递参数,被包含的文件接收到参数以后可以进行适当的处理。

path.php
<?php
echo "This is file path.php<br />\n";
include 'http://www.test2.com/research/path/path1.php?a=comefrom_path.php';
echo "name: $name<br />\n";
?>

path1.php
<?php
$a = $_REQUEST['a'];
echo '<?php $name = "caihuafeng ' . $a . '"; ?>';
?>

下面这些代码是php手册中的:
<?php

/* This example assumes that www.example.com is configured to parse .php *
* files and not .txt files. Also, 'Works' here means that the variables *
* $foo and $bar are available within the included file.                 */

// Won't work; file.txt wasn't handled by www.example.com as PHP
include 'http://www.example.com/file.txt?foo=1&bar=2';

// Won't work; looks for a file named 'file.php?foo=1&bar=2' on the
// local filesystem.
include 'file.php?foo=1&bar=2';

// Works.
include 'http://www.example.com/file.php?foo=1&bar=2';

$foo = 1;
$bar = 2;
include 'file.txt';  // Works.
include 'file.php';  // Works.

?>

4.总结
php.ini中allow_url_fopen默认为On,allow_url_include默认为Off

一般本地的程序要与远程的程序进行交互,不推荐用include远程文件的方式,用fopen,fsockopen,readfile,file_get_contents,curl这些会比较好一点。

如果用fopen、readfile、file_get_contents打开远程文件时,必须将allow_url_fopen设为On

其中用fsockopen及curl来与远程的程序进行交互比较好,readfile也可以。

fopen: 打开的文件一般用来进行读写,也可以打开远程文件,对打开的远程文件进行操作,一般很少对打开的远程文件进行写操作。
fsockopen: 主要用于打开socket连接,需要指定ip地址及端口,进行相关的读写操作。
readfile: 读入一个文件的内容并且输出此内容,可以包含动态及静态文件,如果是动态文件,则返回的是执行的结果。
file_get_contents: 将整个文件读取一个字符串,可以是动态及静态文件,如果是动态文件,则返回的是执行的结果。

做了如下的一个测试,
file_get_contents包含本地或远程静态文件,则均有结果
file_get_contents包含远程动态文件,有结果返回,包含本地动态文件,无结果返回

readfile包含远程动态文件,有结果返回,包含本地动态文件,无结果返回
readfile包含本地或远程静态文件,则均有结果

echo file_get_contents('1.txt');//I am 1.txt
echo file_get_contents('http://www.test2.com/research/path/1.txt');//I am 1.txt

echo 'file_get_cnotents:' . file_get_contents('http://www.test2.com/research/path/1.php')."<br />\n";//2009-12-13 09:03:19
echo 'file_get_contents:' . file_get_contents('1.php')."<br />\n";//返回为空

readfile('http://www.test2.com/research/path/1.php');//2009-12-13 09:03:19
readfile('1.php');//返回为空

readfile('http://www.test2.com/research/path/1.txt');//I am 1.txt
readfile('1.txt');//I am 1.txt

Tags: php

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 2541

PHP中用file_get_contents抓取网页

1.用 file_get_contents 访问 http 时取回响应头
file_get_contents('http://www.baidu.com/');
var_dump($http_response_header);
输出如下:
array(9) {
  [0]=>
  string(15) "HTTP/1.1 200 OK"
  [1]=>
  string(35) "Date: Sun, 13 Dec 2009 10:46:32 GMT"
  [2]=>
  string(15) "Server: BWS/1.0"
  [3]=>
  string(20) "Content-Length: 3520"
  [4]=>
  string(38) "Content-Type: text/html;charset=gb2312"
  [5]=>
  string(22) "Cache-Control: private"
  [6]=>
  string(38) "Expires: Sun, 13 Dec 2009 10:46:32 GMT"
  [7]=>
  string(121) "Set-Cookie: BAIDUID=0D6BDA29200E9DC5B9F4674B6884C9D1:FG=1; expires=Sun, 13-Dec-39 10:46:32 GMT; path=/; domain=.baidu.com"
  [8]=>
  string(39) "P3P: CP=" OTI DSP COR IVA OUR IND COM ""
}

在用 file_get_contents 访问 http 时,stream wrapper 会把响应头放到当前作用域下的 $http_response_header 数组变量里,详细可以看这儿

 

2.向被请求的url中传递参数
test.php
<?php
$opts = array(
  'http'=>array(
    'timeout'=>10,
    'header'=>"User-Agent: php\r\n" .
              "Cookie: foo=bar\r\n"
  )
);
$context = stream_context_create($opts);
echo file_get_contents('http://localhost/research/test1.php', false, $context);

查看更多...

Tags: php

分类:技术文章 | 固定链接 | 评论: 0 | 引用: 0 | 查看次数: 1882

 广告位

↑返回顶部↑