分类 PHP 下的文章

近日有客服人员反馈,线上后台管理系统二三十分钟没使用,即时也没没关闭也会自动退出登录,不太符合实际使用场景。
经过观察发现,其实测试线的系统就不会有这种情况发现,同样的代码,只是服务器不同,得出结论是php配置不一致导致。
对比发现,是php.ini的session.gc_maxlifetime 配置的值不同,正式线的是默认值 1440 (24分钟),
调整为86400,(一天)

操作如下

vim /usr/local/php/etc/php.ini
session.gc_maxlifetime = 86400 #设置为1天,也可以根据系统需要调整

调整完php.ini之后需要重启php-fpm生效,
1、如果服务器已经把php-fpm加入到service那么重启很简单

service php-fpm restart

2、如果php-fpm并未加入service,可用以下方法重启

1)ps -ef | grep php-fpm | grep master #获取到 php-fpm主进程的 进程id
2)kill -USR2 进程id  #重启进程

3、如果存在/usr/local/php/var/run/php-fpm.pid 文件,可用直接执行一下命令重启

 kill -USR2 `cat /usr/local/php/var/run/php-fpm.pid`

重启完php-fpm之后,重新登录后台管理账号,就不会出现几十分钟退出登录的情况

sql注入攻击

说到安全性问题,首当其冲必定是sql注入问题.所谓的sql注入,就是攻击者在提交数据的时候,会在里面加入一些特殊字符,达到获取数据库访问权限或者破坏数据的目的。
例如,登录功能

sql = "select * from user_table where username=
' "+userName+" ' and password=' "+password+" '";

当用户输入的username = '’or 1 = 1 -- and password='’

sql语句变成
SELECT * FROM user_table WHERE username=
'’or 1 = 1 -- and password='’
条件后面username='' or 1=1 是必定成立的,--是注释后面的sql语句,所以攻击者就轻松绕过了密码验证

那么如何防御sql注入呢,简单的说,就是不要相信任何用户提交过来的数据,具体如下

  1. 严格按照字段所需的格式进行格式化,比如数字就格式化为数字接受,字符串几格式化为字符串接收。
  2. 使用addslashes函数来将单引号、双引号、反斜杠、null等字符前面加上斜杆,使其不具有特殊字符意义。
  3. 使用htmlspecialchars方法来对用户提交的数据进行解析。
  4. 绑定变量,使用预编译语句防止注入。

xss跨站攻击

跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的特殊目的。
防范xss攻击也很简单,一样不要相信用户提交的任何数据,把用户所有的数据都加个htmlspecialchars处理。

csrf跨站伪造请求

跨站伪造请求是攻击者通过一些技术手段欺骗用户去访问曾经认证过的网站,并运行一些操作。可以理解为攻击者盗用了你的身份,以你的名义发送恶意请求。
主要步骤是

  • 用户登录网站A,并在本地生成cookie。
  • 在不登出网站A的情况下,访问危险网站B。

那么如何防御csrf攻击呢

  • 最简单的方法应该是加入页面token了,即每个页面都生成一个随机的token,服务端接收操作指令的时候验证一下。
  • 使用cookie hashing的方式,即每个表单都包含同一个随机数,然后在服务端进行hash验证。
  • 增加隐藏字段验证,或者表单结构验证。

相信很多phper们在使用composer添加新插件的时候,会碰到这个问题:”明明这次要安装的是一个新插件,结果提示其他插件安装报错“。
类似的报错如:

Your requirements could not be resolved to an installable set of packages.
Problem 1
    - phpoffice/phpspreadsheet is locked to version 1.7.0 and an update of this package was not requested.
    - phpoffice/phpspreadsheet 1.7.0 requires ext-zip * -> it is missing from your system. Install or enable PHP's zip extension.
  Problem 2
    - topthink/think-installer v2.0.0 requires composer-plugin-api ^1.0 -> found composer-plugin-api[2.1.0] but it does not match the constraint.
    - topthink/framework v5.1.23 requires topthink/think-installer 2.* -> satisfiable by topthink/think-installer[v2.0.0].
    - topthink/framework is locked to version v5.1.23 and an update of this package was not requested.

其实要解决这个问题很简单,只需要执行一下代码:

composer install --ignore-platform-reqs

composer update --ignore-platform-reqs

忽略掉composer的版本匹配,这样就可以继续正常安装新的包了,快去试试吧

都说网络爬虫就用python,但我不这么认为。
尤其是对于熟悉php又对python生疏的coder来说,其实完全不比舍近求远。
只要插件用的好,就没有php办不了的事儿,今天要给大家介绍的这款插件是PHP Simple HTML DOM Parser,html页面解析插件,效率之高,令人拍手叫绝(偷笑),而且操作简便,可以像jquery一样去获取html标签。实在是居家旅行,页面抓取,必备神器。

相关资源

操作手册:https://simplehtmldom.sourceforge.io/manual.htm
下载地址:https://sourceforge.net/projects/simplehtmldom/files/

获取远程地址html元素

// 新建一个dom实例
$html = file_get_html('http://www.baidu.com/');

// 获取所有img标签
foreach($html->find('img') as $element)
  echo $element->src . '<br>';

// 获取所有连接
foreach($html->find('a') as $element)
  echo $element->href . '<br>'; 

直接操作html字符串

// 根据字符串创建dom实例
$html = str_get_html('<html><body>Hello!</body></html>');

获取单个元素

// 获取第一个a标签元素
$ret = $html->find('a', 0);

// 获取最后一个a标签元素
$ret = $html->find('a', -1); 

获取元素值

// 创建Dom实例
$html = file_get_html('http://www.baidu.com/');

// 获取所有a标签的链接地址
foreach($html->find('a') as $e) 
    echo $e->href . '<br>';

// 获取所有img标签的src地址
foreach($html->find('img') as $e)
    echo $e->src . '<br>';

// 获取所有的img标签内容
foreach($html->find('img') as $e)
    echo $e->outertext . '<br>';

// 获取标签id=gbar的div标签内容
foreach($html->find('div#gbar') as $e)
    echo $e->innertext . '<br>';

// 获取标签id=gbar的div标签的文本信息
foreach($html->find('div#gbar') as $e)
    echo $e->plaintext . '<br>';

如何操作Dom树

// 示例
echo $html->find("#div1", 0)->children(1)->children(1)->children(2)->id;



- 阅读剩余部分 -

众所周知,高质量的代码可以减轻服务器的压力,同时也能让人赏心悦目。
以下是本人近期总结的优化技巧:

  1. 能不用正则解决的问题,尽量不用正则;
  2. 在includes和requires中使用绝对路径,这样在分析路径花的时间更少;
  3. 使用requiere_once代价比requiere高;
  4. str_replace函数比preg_replace函数快,但strtr函数的效率是str_replace函数的四倍;
  5. 多个分支的条件判断用switch、case优于if、elseif;
  6. 尽量少用@屏蔽错误,这样做效率灰常低;
  7. echo 比 print快,echo 可以打印用逗号分割的字符串;
  8. 执行for循环之前确定最大循环数,而不是每次循环都去计算最大值,可以的话尽量使用foreach代替;
  9. 尽量使用PHP的内置函数;
  10. 并不是所有情况都必须使用面向对象开发,面向对象往往开销很大,每个方法和对象调用都会消耗很多内存;
  11. 如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍;
  12. 递增一个对象属性,要比递增一个局部变量慢3倍;
  13. 派生类中的方法运行起来要快于在基类中定义的同样的方法;
  14. 用单引号替代双引号引用字符串;
  15. 在可以用file_get_contents替代file、fopen、feof、fgets等系列方法的情况下,尽量用 file_get_contents,因为他的效率高得多;
  16. 尽量做缓存,例如 memcached、redis;
  17. 尽量多用静态HTML页面,少用脚本,服务器解析一个PHP脚本的时间要比一个静态html页面要慢2-10倍;
  18. 尽量少用global变量,对global变量,应该用完就unset()掉;
  19. 禁止过多的循环套循环,嵌套过多的循环会拉低执行效率;
  20. 开启服务器gzip压缩。