分类 Php 下的文章

Linux下快速PHP编译安装fileinfo扩展

1、进入对应php版本扩展目录:

cd /opt/php-7.2.12/ext/fileinfo

2、编译及安装

/usr/local/php/bin/phpize
./configure -with-php-config=/usr/local/php/bin/php-config
make
make install

3、修改php.ini

extension = fileinfo.so

4、重启php-fpm生效

systemctl restart php-fpm

PHP7使用Redis保存session

PHP默认就支持保存session到redis,不需任何额外代码,首先安装redis,参考 redis快速安装
PHP默认使用文件存储session,如果并发量大,效率非常低,如项目同时运行在多台服务器上做了分布式部署,就无法使用常规的Session记录方式来记录用户的会话了,否则用户在服务器1上完成登录,我们下次在服务器2上访问其他模块就无法获取到该用户的信息。
php-redis.png



---阅读剩余部分---

opcache参数配置优化详解

我们在日常的PHP开发过程中,应该经常会听见Opcache这个词,那么啥是Opcode呢?
Install-OPcache-in-CentOS-7.png
Opcache 的前生是 Optimizer+ ,它是PHP的官方公司 Zend 开发的一款闭源但可以免费使用的 PHP 优化加速组件。 Optimizer+ 将PHP代码预编译生成的脚本文件 Opcode 缓存在共享内存中供以后反复使用,从而避免了从磁盘读取代码再次编译的时间消耗。同时,它还应用了一些代码优化模式,使得代码执行更快。从而加速PHP的执行。

Optimizer+ 于 2013年3月中旬改名为 Opcache。并且在 PHP License 下开源: https://github.com/zendtech/ZendOptimizerPlus



---阅读剩余部分---

php-fpm.conf参数说明

php-fpm.conf参数说明:
1、pm = dynamic 对于专用服务器,pm可以设置为static。
如何控制子进程,选项有static和dynamic。

如果选择static,则由pm.max_children指定固定的子进程数。
如果选择dynamic,则由pm.max_children、pm.start_servers、pm.min_spare_servers、pm.max_spare_servers 参数决定:
pm.max_children:静态方式下开启的php-fpm进程数量。
pm.start_servers:动态方式下的起始php-fpm进程数量。
pm.min_spare_servers:动态方式下的最小php-fpm进程数量。
pm.max_spare_servers:动态方式下的最大php-fpm进程数量。


---阅读剩余部分---

php的session过期时间

PHP从4.0中加入了对Session的支持,方便了我们开发,Session储存在服务器端,根据客户端 提供的SessionID来得到这个用户的文件,然后读取文件,取得变量的值,SessionID可以使用客户端的Cookie或者Http1.1协议的 Query_String(就是访问的URL的“?”后面的部分)来传送给服务器,然后服务器读取Session的目录。

先来看看在php.ini中session怎么设置,打开 php.ini,查找Session设置部分中以下一项,代码如下:

session.save_path = "N;/path"
session.save_path = "C:/Temp"  #此处以你自己设定的路径为准

这项设置提供给我们可以给session存放目录进行多级散列,其中“N”表示要设置的目录级数,后面的“/path”表示session文件存放的根目录路径,比如我们设置为下面的格式,代码如下:

session.save_path = "2;C:/Temp"

上面的设置表示我们把php的session文件进行两级目录存储,每一级目录分别是0-9和a-z共36个字母数字为目录名,这样存放session的目录可以达到36*36个,共1332个文件夹,相信作为单台服务器来说,这是完全够用了,如果说您的系统架构设计为多台服务器共享session数据,可以把目录级增加到3级或者更多。

session.gc_maxlifetime = 1440 #(PHP5默认24分钟)
session.gc_probability = 1
session.gc_divisor = 1000   #garbage collection 有个概率的,1/1000就是session 1000次才有一次被回收。

将session.gc_divisor = 0,这样就能明显的看到SESSION过期的效果了.

session有过期的机制:
session.gc_maxlifetime 原来session 过期是一个小概率的事件,分别使用session.gc_probability和session.gc_divisor 来确定运行session 中gc 的概率 session.gc_probability和session.gc_divisor的默认值分别为 1和100。分别为分子和分母 所以session中gc的概率运行机会为1% 。如果修改这两个值,则会降低php的效率。

概率是gc_probability/gc_divisor

session.gc_probability = 1
session.gc_divisor = 100

注意1:假设这种情况gc_maxlifetime=120,如果某个session文件最后修改时间是120秒之前,那么在下一次回收(1/100的概率)发生前,这个session仍然是有效的。

注意2:如果你的session使用session.save_path中使用别的地方保存session,session回收机制有可能不会自动处理过期session文件。这时需要定时手动(或者crontab)的删除过期的session:

cd /path/to/sessions; find -cmin +24 | xargs rm

PHP中的session永不过期

不修改程序是最好的方法了,因为如果修改程序,测试部一定非常郁闷,那么只能修改系统环境配置,其实很 简单,打开php.ini设置文件,修改三行如下:

1、session.use_cookies

把这个的值设置为1,利用cookie来传递sessionid

2、session.cookie_lifetime

这个代表SessionID在客户端Cookie储存的时间,默认是0,代表浏览器一关闭SessionID就作废……就是因为这个所以PHP的 session不能永久使用! 那么我们把它设置为一个我们认为很大的数字吧,999999999怎么样,可以的!就这样。

3、session.gc_maxlifetime

这个是Session数据在服务器端储存的时间,如果超过这个时间,那么Session数据就自动删除! 那么我们也把它设置为99999999。

就这样一切ok了,当然你不相信的话就测试一下看看——设置一个session值过个10天半个月的回来看看,如果你的电脑没有断电或者宕机,你仍然可以看见这个sessionid。

via: http://php.net/manual/zh/session.configuration.php#ini.session.gc-divisor

Chrome浏览器对于POST页面执行history.back返回或表单数据丢失的解决办法

PHP页面POST数据页面时,都会都POST的数据进行校验,如果不符合的数据或是空项我们都会给出提示,并返回前一个页面。但是经常发现有用户提出,会出现返回后当前页面所填写的内容都丢失了,或是出现页面无法显示的问题。

确认重新提交表单 此网页需要使用您之前输入的数据才能正常显示。您可以重新发送这些数据,不过,这么做会重复执行此网页之前执行过的所有操作。
按“重新加载”按钮,重新提交加载该网页所需的数据。
ERR_CACHE_MISS

如下图:
post-page.png

原因:
是因为使用session_start()的问题,我们可以这样处理,在你的 Session_start 函数后加入 header("Cache-control:private");
"private" 则表示该响应是专用于某单个用户的,中间人不能缓存此响应,该响应只能应用于浏览器私有缓存中。
注意在本行之前你的PHP程序不能有任何输出。
解决方法如下:

session_start();//开启session功能,此前不能有任何输出
header("Cache-control:private"); //开启网页表单缓存,一定要放在Session_start 函数后

在此测试,问题解决。
via: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Caching_FAQ

PHP过滤输入表单XSS\HTML特殊字符等预防WEB攻击

hacker.png
Web应用系统的攻击大部分是来自于外部,如Url上添加一些字段注入($_GET输入),表单的提交注入(一般为$_POST),所以在接收数据时对数据进行过滤,是必须的:
过滤方法有以下几种:
trim过滤字符串首尾空格

$test1 = trim($_POST['test1']);

strip_tags函数过滤PHP、HTML标签 :
strip_tags会将字符串中的php标签(<?php ?>)Html标签(<h1></h1><script></script>....等)移除。一定程序上阻止了恶意注入。

$_POST['name'] = "<script>alert('hehe');</script>";
var_dump($_POST['name']);//弹出信息框 'hehe'
$name = strip_tags($_POST['name']);
var_dump($name);  //string(14) "alert('hehe');"

转数据类型
接收的数据是整形或浮点形,可以直接转数据类型。

//转整形 
$number = intval($_POST['number']);
$price  = floatval($_POST['price']);

移除攻跨站脚本xss攻击
xss攻击有时会把标签转换成其他数据,strip_tags防止不了,
ThinkPHP中有个remove_xss方法,可以将大部分xss攻击阻止。./ThinkPHP/Extend/Function/extend.php中,为了方便使用,可以放到项目的common.php里或公用文件里面直接调用:

/**
 * @from extend.php
 * 过滤xss攻击
 * @param str $val
 * @return mixed
 */
function remove_xss($val) {
    // remove all non-printable characters. CR(0a) and LF(0b) and TAB(9) are allowed
    // this prevents some character re-spacing such as <java\0script>
    // note that you have to handle splits with \n, \r, and \t later since they *are* allowed in some inputs
    $val = preg_replace('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/', '', $val);

    // straight replacements, the user should never need these since they're normal characters
    // this prevents like <IMG SRC=@avascript:alert('XSS')>
    $search = 'abcdefghijklmnopqrstuvwxyz';
    $search .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $search .= '1234567890!@#$%^&*()';
    $search .= '~`";:?+/={}[]-_|\'\\';
    for ($i = 0; $i < strlen($search); $i++) {
        // ;? matches the ;, which is optional
        // 0{0,7} matches any padded zeros, which are optional and go up to 8 chars

        // @ @ search for the hex values
        $val = preg_replace('/(&#[xX]0{0,8}'.dechex(ord($search[$i])).';?)/i', $search[$i], $val); // with a ;
        // @ @ 0{0,7} matches '0' zero to seven times
        $val = preg_replace('/(&#0{0,8}'.ord($search[$i]).';?)/', $search[$i], $val); // with a ;
    }

    // now the only remaining whitespace attacks are \t, \n, and \r
    $ra1 = array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'style', 'script',
                  'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');
    $ra2 = array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut',
             'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 
             'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut',
             'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend',
             'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange',
             'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete',
             'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover',
             'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange','onreadystatechange',
             'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 
             'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
    $ra = array_merge($ra1, $ra2);

    $found = true; // keep replacing as long as the previous round replaced something
    while ($found == true) {
        $val_before = $val;
        for ($i = 0; $i < sizeof($ra); $i++) {
            $pattern = '/';
            for ($j = 0; $j < strlen($ra[$i]); $j++) {
                if ($j > 0) {
                    $pattern .= '(';
                    $pattern .= '(&#[xX]0{0,8}([9ab]);)';
                    $pattern .= '|';
                    $pattern .= '|(&#0{0,8}([9|10|13]);)';
                    $pattern .= ')*';
                }
                $pattern .= $ra[$i][$j];
            }
            $pattern .= '/i';
            $replacement = substr($ra[$i], 0, 2).'<x>'.substr($ra[$i], 2); // add in <> to nerf the tag
            $val = preg_replace($pattern, $replacement, $val); // filter out the hex tags
            if ($val_before == $val) {
                // no replacements were made, so exit the loop
                $found = false;
            }
        }
    }
    return $val;
}

调用方法:

$name = remove_xss($_POST['name']);
也可以和strip_tags结合起来使用
$name = strip_tags(remove_xss($_POST['name']));

保存文章内容类转义:
使用kindeditor之类的内容编辑器时,因为提交到后台时是以Html形式提交的,而且需要保存到数据库,为了防止sql注入,需要在进数据库前进行特殊字符转义,这时用过滤标签的方法或各类的方法都不适合。只能对标签和特殊符号进行转义,这时使用到的方法是addslashes。
addslashes在使用前先检查一下,php是否自动开启了自动转义。用get_magic_quotes_gpc()方法判断,如果已开,则是true,否为false。

    if(!get_magic_quotes_gpc()){
     $content = addslashes($_POST['content']);
    }else{
      $content= $_POST['content'];
    }

这样就完成了转义,然而在展示页面,从数据库拿出来的内容是经过转义的html,如果直接展示,html标签等都识别不到,会直接输出转义过的字符串。这时需要用反转义来还原数据。如下

echo stripslashes($content);

PHP内置过滤器参考使用 PHP内置过滤器filter_input
其他参考:
http://www.w3school.com.cn/php/func_filter_input_array.asp
https://my.oschina.net/jiec/blog/309467

JS弹出确认删除的提示信息

在后台管理系统中,在一些重要操作如删除按钮或连接被触发时,应给予弹窗提示,常用的代码有以下几种:
用户点击删除按钮时,弹出一个确定框,如果用户点击“确定”执行删除操作,否则不执行
1、通过链接来删除数据出现提示

<a href="del.php?id=1" onclick="return confirm('您确定删除该记录吗?')">删除</a>

2、通过提交表单来删除,也就是批量删除多条数据

<script type="text/javascript"> 
function DelFromLst(){  
        if(confirm('确认删除已选择数据吗?')){
          document.selform.action.value='batdel';
          document.selform.submit();
        }
}
</script>

这里的按钮是 button类型的,不是submit。

<input type="button" name="delbtn" value="批量删除" /> 

3、直接使用js方法

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>确认是否删除</title> 
<script type="text/javascript"> 
function del(){ 
if(!confirm("确认要删除?")){ 
window.event.returnValue = false; 
} 
} 
</script> 
</head> 
<body> 
<a href="http://www.baidu.com" onclick="return del()">删除</a> 
</body> 
</html>

PHP内置过滤器filter_input

定义和用法
filter_input() 函数从脚本外部获取输入,并进行过滤。
函数用于对来自非安全来源的变量进行验证,比如用户的输入。

本函数可从各种来源获取输入:

INPUT_GET
INPUT_POST
INPUT_COOKIE
INPUT_ENV
INPUT_SERVER
INPUT_SESSION (Not yet implemented)
INPUT_REQUEST (Not yet implemented)
//验证(validation) Filters
FILTER_VALIDATE_BOOLEAN:  把值作为布尔选项来验证,对 "1", "true", "on" 和 "yes" 返回 TRUE, 其余的都返回 FALSE
FILTER_VALIDATE_EMAIL:    把值作为邮件地址来验证
FILTER_VALIDATE_FLOAT:    把值作为浮点数来验证
FILTER_VALIDATE_INT:      以整数验证值,可以选择范围
FILTER_VALIDATE_IP:       把值作为 IP 进行验证
FILTER_VALIDATE_REGEXP:   根据兼容 Perl 的正则表达式来验证值
FILTER_VALIDATE_URL:      把值作为 URL 进行验证
//纠错(sanitization) Filters
FILTER_SANITIZE_EMAIL:         移除所有字符, 除了字母,数字和 !#$%&'*+-/=?^_`{|}~@.[].
FILTER_SANITIZE_ENCODED:       去除 URL 编码不需要的字符, 与 urlencode() 函数很类似
FILTER_SANITIZE_MAGIC_QUOTES:  在指定的预定义字符前添加反斜杠, 单引号(')、双引号(")、反斜线(\)与 NULL
FILTER_SANITIZE_NUMBER_FLOAT:  移除所有字符, 除了数字,+- 和可选(.,)
FILTER_SANITIZE_NUMBER_INT:    移除所有字符, 除了数字和 +-
FILTER_SANITIZE_SPECIAL_CHARS: 用于对 "<>& 以及 ASCII 值在 32 值以下的字符进行转义
FILTER_SANITIZE_STRING:        删除那些对应用程序有潜在危害的数据。它用于去除标签以及删除或编码不需要的字符
FILTER_SANITIZE_STRIPPED:      去除或编码不需要的字符,是 FILTER_SANITIZE_STRING 的别名
FILTER_SANITIZE_URL:           移除所有字符, 除了字母,数字和 $-_.+!*'(),{}|\\^~[]`<>#%";/?:@&=.
FILTER_UNSAFE_RAW:             不进行任何过滤,去除或编码特殊字符

如果成功,则返回被过滤的数据,如果失败,则返回 false,如果 variable 参数未设置,则返回 NULL。

语法

filter_input(input_type, variable, filter, options)

参数 描述
input_type 必需。规定输入类型。参见上面的列表中可能的类型。
variable 规定要过滤的变量。
filter
可选。规定要使用的过滤器的 ID。默认是 FILTER_SANITIZE_STRING。

请参见完整的 PHP Filter 函数参考手册,获得可能的过滤器。

过滤器 ID 可以是 ID 名称 (比如 FILTER_VALIDATE_EMAIL),或 ID 号(比如 274)。

options 规定包含标志/选项的数组。检查每个过滤器可能的标志和选项。
例子
在本例中,我们使用 filter_input() 函数来过滤一个 POST 变量。所接受的 POST 变量是合法的 e-mail 地址。

<?php
if(!filter_input(INPUT_GET,'p',FILTER_VALIDATE_INT)) //p变量只接收整型数据,输入特殊符号等都会重置为1
{
    $p = 1;
}else{
    @$p = $_GET['p']?$_GET['p']:1;
}
<?php
#PHP内置的validate filter
$input_data = True;
$result = filter_var($input_data,FILTER_VALIDATE_BOOLEAN);
#FILTER_VALIDATE_BOOLEAN对应验证布尔值
var_dump($result); #因为input_data是真,所以结果是 True
$input_data = 123;
$result = filter_var($input_data,FILTER_VALIDATE_BOOLEAN);
var_dump($result); #因为input_data是123数字类型,所以结果是 False
/*
filter_var 函数有三个参数 分别是 输入数据 filter对应的id 和选项
输入数据类型可以是多种的
filter的对应id在这里可以查看列表 http://www.php.net/manual/zh/filter.filters.php
选项是一个关联数组 可以在上面的地址中查看可以使用的选项,也可以自己使用回调函数来处理输入数据
*/
#使用回调例子
function callback_filter($value) #回调函数
{
return $value.'_callback';
}
$result = filter_var('input',FILTER_CALLBACK,array('options'=>'callback_filter'));
var_dump($result);
#验证一个非10进制的整数
#8进制
$result = filter_var('0755', FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL));
var_dump($result);
#16进制
$result = filter_var('0XAF', FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_HEX));
var_dump($result);
#注意这里输出的结果是10进制的
#当验证失败时设置默认值  因为字符a不是整数,所以在无法通过验证的时候被强制替换成了默认值123 
$result = filter_var('a',FILTER_VALIDATE_INT,array('options'=>array('default'=>123)));
var_dump($result);
#限制数字范围
$result = filter_var(99,FILTER_VALIDATE_INT,array('options'=>array('default'=>50,'max_range'=>98)));
var_dump($result);
$result = filter_var(99,FILTER_VALIDATE_INT,array('options'=>array('default'=>50,'min_range'=>100)));
var_dump($result);
#min与max可以同时使用
#验证email格式
$result = filter_var('a@a.c',FILTER_VALIDATE_EMAIL);
var_dump($result);
#验证IP
$result = filter_var('192.168.1.1',FILTER_VALIDATE_IP);
var_dump($result);
#FILTER_VALIDATE_IP的flags有四个分别是
#FILTER_FLAG_IPV4, FILTER_FLAG_IPV6, FILTER_FLAG_NO_PRIV_RANGE, FILTER_FLAG_NO_RES_RANGE
#对应 IPV4 IPV6 过滤私有地址 与 过滤保留地址
#验证url
$result = filter_var('http://www.yahoo.com/',FILTER_VALIDATE_URL);
var_dump($result);
#url 有两种flags 其中FILTER_FLAG_QUERY_REQUIRED 要求url中必须包含查询字符串
#FILTER_FLAG_PATH_REQUIRED 要求格式必须包含为/结尾的路径或者包含文件
#简单来说就是 http://aaa.com是不能通过的 但是http://aaa.com/或者http://aaa.com/index.html就可以通过)
#注意 url并不仅限于http与https ,而且目前也只支持ASCII字符,例如中文域名就会失败
#根据正则验证
$result = filter_var('0000112884634874',FILTER_VALIDATE_REGEXP,array('options'=>array('regexp'=>"/\d+/")));
var_dump($result);
#在php 5.4.11之前 +0与-0只能通过float验证,在5.4.11之后可以通过int和float验证
#以上就是PHP内置的几种validate filter,下回介绍其他filter


#Sanitize filters
#Sanitize filters 可以清理掉不规范的字符
# FILTER_SANITIZE_EMAIL 可以清理除了 字母和数字 以及  !#$%&'*+-/=?^_`{|}~@.[] 以外的字符  (感觉没什么用啊)
$result = filter_var('这里是一个email地址asdjaslkd@sdjkasdj.com',FILTER_SANITIZE_EMAIL);
var_dump($result);
# FILTER_SANITIZE_ENCODED 处理URL编码 有4个flags
# FILTER_FLAG_STRIP_LOW - 去除 ASCII 值在 32 以下的字符
# FILTER_FLAG_STRIP_HIGH - 去除 ASCII 值在 32 以上的字符
# FILTER_FLAG_ENCODE_LOW - 编码 ASCII 值在 32 以下的字符
# FILTER_FLAG_ENCODE_HIGH - 编码 ASCII 值在 32 以上的字符
# 感觉还是urlencode函数更实用
$result = filter_var('http://www.longxiao7.com',FILTER_SANITIZE_ENCODED);
var_dump($result);
# FILTER_SANITIZE_MAGIC_QUOTES  等同于  addslashes 函数
# FILTER_SANITIZE_NUMBER_FLOAT 删除浮点数中所有非法的字符 此FILTER可能存在的flags如下
# FILTER_FLAG_ALLOW_FRACTION  允许小数部分
# FILTER_FLAG_ALLOW_THOUSAND  允许千分位计数
# FILTER_FLAG_ALLOW_SCIENTIFIC 允许科学计数
$result = filter_var('0.54548',FILTER_SANITIZE_NUMBER_FLOAT,FILTER_FLAG_ALLOW_FRACTION);
var_dump($result);
$result = filter_var('1000,000,000',FILTER_SANITIZE_NUMBER_FLOAT,FILTER_FLAG_ALLOW_THOUSAND);
var_dump($result);
$result = filter_var('1E20',FILTER_SANITIZE_NUMBER_FLOAT,FILTER_FLAG_ALLOW_SCIENTIFIC);
var_dump($result);
# FILTER_SANITIZE_NUMBER_INT 过滤整数以外的字符
$result = filter_var('54548)*)(……&*%6554……¥测试字符.055',FILTER_SANITIZE_NUMBER_INT);
var_dump($result);
# FILTER_SANITIZE_SPECIAL_CHARS  处理HTML转义字符 '"<>& 以及 ASCII 值小于 32 的字符
# flags
# FILTER_FLAG_STRIP_LOW - 去除 ASCII 值在 32 以下的字符
# FILTER_FLAG_STRIP_HIGH - 去除 ASCII 值在 32 以上的字符
# FILTER_FLAG_ENCODE_HIGH - 编码 ASCII 值在 32 以上的字符
$result = filter_var('<script>alert(\'&nbsp;中文\')</script>',FILTER_SANITIZE_SPECIAL_CHARS);
var_dump($result);
# FILTER_SANITIZE_FULL_SPECIAL_CHARS 上面那个加强版?貌似和htmlspecialchars函数是一样的
#FILTER_SANITIZE_STRING 过滤器去除或编码不需要的字符。
# flags
# FILTER_FLAG_NO_ENCODE_QUOTES - 该标志不编码引号
# FILTER_FLAG_STRIP_LOW - 去除 ASCII 值在 32 以下的字符
# FILTER_FLAG_STRIP_HIGH - 去除 ASCII 值在 32 以上的字符
# FILTER_FLAG_ENCODE_LOW - 编码 ASCII 值在 32 以下的字符
# FILTER_FLAG_ENCODE_HIGH - 编码 ASCII 值在 32 以上的字符
# FILTER_FLAG_ENCODE_AMP - 把 & 字符编码为 &amp;
$result = filter_var('<script>alert(\'&nbsp;中文\')</a>',FILTER_SANITIZE_STRING,FILTER_FLAG_ENCODE_AMP);
var_dump($result);
# FILTER_SANITIZE_URL 可以清理除了 字母和数字 以及 $-_.+!*'(),{}|\\^~[]`<>#%";/?:@&=以外的字符
# FILTER_UNSAFE_RAW 感觉意义不大,需要配合flags才能工作 详见PHP手册

PHP提示Notice: Undefined variable的解决办法

PHP默认配置会报这个错误,我的PHP版本是5.x及7.x都存在这个问题:
Notice: Undefined variable
这就是将警告在页面上打印出来,虽然这是有利于暴露问题,但实现使用中会存在很多问题。

需要设置显示错误级别,来解决问题。
通用解决办法是修改php.ini的配置:
解决方法:

1) error_reporting设置:

找到error_reporting = E_ALL
修改为error_reporting = E_ALL & ~E_NOTICE

2) register_globals设置:

找到register_globals = Off
修改为register_globals = On

在php代码中直接顶部增加一句

ini_set("error_reporting","E_ALL & ~E_NOTICE");

也可解决;

使用echarts在饼图上显示数据

默认的ECharts饼图上不显示数据,官方例子http://echarts.baidu.com/demo.html#pie-simple ,要在饼图上显示数据,需修改下js代码,实现代码如下:

<script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('main'));
        option = {
            title : {
                text: '2017项目上线发布次数',
                subtext: '工程',
                x:'center'
            },
            tooltip : {
                trigger: 'item',
                formatter: "{a} <br/>{b} : {c} ({d}%)"
            },
            legend: {
                orient: 'vertical',
                left: 'left',
                <?php
                $usergroup_sql = "SELECT project_name,project_type,SUM(project_num) AS heji FROM ops_project_number WHERE project_type = '工程' GROUP BY project_name ORDER BY heji DESC;";
                $usresult = $conn->query($usergroup_sql);
                echo 'data:[ ';
                while($urow = mysqli_fetch_row($usresult)) {
                    echo "'$urow[0]',";
                }
                echo "]";
                ?>
            },
            series : [
                {
                    name: '发布次数',
                    type: 'pie',
                    radius : '80%',
                    center: ['50%', '60%'],
                    data:[
                        <?php
                        $usergroup_sql = "SELECT project_name,project_type,SUM(project_num) AS heji FROM ops_project_number WHERE project_type = '工程' GROUP BY project_name ORDER BY heji DESC;";
                        $usresult = $conn->query($usergroup_sql);
                        //echo 'data:[ ';
                        while($urow = mysqli_fetch_row($usresult)) {
                            echo "{value:$urow[2], name:'$urow[0]'},";
                        }
                        ?>
                    ],
                    itemStyle: {
                        normal:{
                            label:{
                                show: true,
                                formatter: '{b} : {c} ({d}%)'
                            },
                            labelLine :{show:true}
                        }
                    }
                }
            ]
        };
        // 使用刚指定的配置项和数据显示图表。
        myChart.setOption(option);
    </script>

展示效果:
et.png

php中调用系统命令

hp提供了system(),exec(),passthru()这三个函数来调用外部的命令.
虽然这三个命令都能执行linux系统的shell命令,但是其实他们是有区别的:
system() 输出并返回最后一行shell结果。
exec() 不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面。
passthru() 只调用命令,把命令的运行结果原样地直接输出到标准输出设备上。

相同点:都可以获得命令执行的状态码

在PHP中调用外部命令,可以用如下三种方法来实现:

1) 用PHP提供的专门函数
PHP提供了3个专门的执行外部命令的函数:system(),exec(),passthru()。
system()
原型:string system (string command [, int return_var])
system()函数和其它语言中的差不多,它执行给定的命令,输出和返回结果。第二个参数是可选的,用来得到命令执行后的状态码。









---阅读剩余部分---

php页面调用vnstat显示机器网卡流量

在php页面上实时显示网卡流量,调用的是vnstat,可以实时、按小时、按月份统计网卡流量
通用安装

debian/ubuntu安装
apt-get install vnstat -y
/etc/init.d/vnstat start
update-rc.d vnstat enable
或
RHEL/CentOS安装:
yum install vnstat -y
/etc/init.d/vnstat start
chkconfig vnstat on

vnstat基本使用命令
vnstat -i eth0 -l #实时流量情况
vnstat -i eth0 -h #按小时查询流量情况
vnstat -i eth0 -d #按天数查询流量情况
vnstat -i eth0 -m #按月数查询流量情况
vnstat -i eth0 -w #按周数查询流量情况
vnstat -i eth0 -t #查询TOP10流量情况
vnstat -i eth0 -q #查询vnstat数据库流量情况
更多命令帮助信息可以 vnstat --help 进行查看。










---阅读剩余部分---

php扩展redis模块

1、到https://github.com/nicolasff/phpredis/下载phpredis最新版
2、将刚下好的压缩包解压到php源码目录下的ext中,即/opt/php-NN/ext/phpredis
mv phpredis-NN /opt/php-NN/ext/phpredis
3、将phpredis加入php拓展模块

cd /opt/php-NN/ext/phpredis
/usr/local/php5/bin/phpize  (如果在编译php时configure没有加足够的参数可能会在目录下缺少phpize)
./configure --with-php-config=/usr/local/php5/bin/php-config (同样后面参数也很重要)
make 
make install

Installing shared extensions: /usr/local/php5/lib/php/extensions/no-debug-non-zts-20121212/

编辑php.ini
加入参数:

extension_dir = "/usr/local/php5/lib/php/extensions/no-debug-non-zts-20121212/"
extension=redis.so

重启php-fpm和nginx即可

LNMP环境“Undefined class constant 'MYSQL_ATTR_INIT_COMMAND'”解决办法

错误问题日志:

2017/05/20 23:44:20 [error] 12171#0: *5 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Undefined class constant 'MYSQL_ATTR_INIT_COMMAND' in /data/www/zg/core/library/dbpdo.class.php on line 15" while reading response header from upstream

Nginx前台直接500了,主要是php没有安装pdo,而程序里面链接用的是pdo_mysql,解决方法如下:
下载并安装PDO_MYSQL


---阅读剩余部分---

对MVC模式的一些理解和看法

模型 (Model)
模型代表了程序逻辑。(在企业级程序中经常称为业务层(business layer))
总的来说,模型的任务是把原有数据转换成包含某些意义的数据,这些数据将被视图所显示。通常,模型将封装数据查询,可能通过一些抽象数据类(数据访问层)来实现查询。



---阅读剩余部分---

最新

分类

归档

评论

  • 安安: 都是af
  • Liang: 嗯,有点不通顺·
  • 王庭威: “MySQL互为主从...
  • Liang: 贴下编译参数和步骤,...
  • shao3911: 您好,为什么我在编译...
  • aliang: 先看是yum安装还是...
  • aliang: 将原来的nginx安...
  • yen: 3、如果要回滚的话,...
  • yen: 刚好需要升级ngin...
  • 文雨: 一些新的method...

其它