前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Php开发过程中不常碰到的error (2.25更新)

Php开发过程中不常碰到的error (2.25更新)

作者头像
猿哥
发布2019-03-13 16:07:55
8600
发布2019-03-13 16:07:55
举报
文章被收录于专栏:Web技术布道师Web技术布道师

文中有些外链如需点击,请到文章底部查看原文。

这里做一些备注,以防再次碰到

url 当中的参数有 &timestamp=1234567890 这样的字段会被转义成 xtamp=1234567890

这个不仅存在于页面解析当中,当使用 curl 请求时拼接的参数有这种格式的也会发生转义

解决方法有两个:

  1. 把 timestamp 这个参数放在 urlQuery 的最前面, ?timestamp=1234567890 这样避免出现 &time发生转义的情况
  2. && 来代替

Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version.

出现这句话通常说明你在用的 php 版本是5.6.而且在 php<=5.6 的时候,进行 application/json格式的 post 提交会把数据放在 $HTTP_RAW_POST_DATA 这个系统变量里面,在 php>=7 的时候这个变量被移除了,统统归总到 php://input 这里

解决方法:

  1. 根据系统提示的走: Although that indeed would be technically impossible (as $HTTP_RAW_POST_DATA is populated in the bootstrapping phase of the PHP process) allow one to override the setting by means of calling ini_set. 要确保自己的系统中没有使用 HTTP_RAW_POST_DATA 这个变量,直接在 php.ini 里面禁掉它的设置,但是容易出现系统中又打开的情况(在框架中很常见)
  2. 改一下自己的提交方式, 使用 application/form-data 或者 application/x-www-form-urlencoded 这种格式的提交, 然后在后端接收数据的时候再转成自己需要的格式(通常是数组) <a href="https://www.bram.us/2014/10/26/php-5-6-automatically-populating-http_raw_post_%20rel=" nofollow,noindex"="" style="box-sizing: border-box; background-color: transparent; color: rgb(66, 139, 202);">参考资料

Exception ‘yii\db\Exception’ with message ‘SQLSTATE[HY000] [2002] No such file or directory’

这种情况出现在平时运行的好好的, 但是突然换 cli 模式后这个配置就出问题了,原因在当 host=localhost 时走的是 unix:socket 链接, 当 host=127.0.0.1 走的是 tcp 链接,这在 php-fpmphp-cli 中有点区别,尤其是本地没有安装 mysql 的时候

解决方法有三种:

  1. 将本地链接配置统一成 127.0.0.1
  2. 查看 MySQL 中的 user 表, host=localhosthost=127.0.0.1 是不是用的同一个账号密码
  3. 配置 php.ini 文件中的 pdo_mysql.default_socket= 写上完整的 socket 路径 以上三种方法都可以试一下 参考资料

常驻内存时发生的事情

这个是 phper 很少碰到但是很常见的情况, 比如用 swoole 启动了一个常驻进程的服务, 那么就一定要小心使用静态变量,在同步模式下会发生变量污染, 还有就是 redis,mysql 这类的链接,你会发现长时间静置以后就会出现一些摸不着头脑的问题, 这种情况不妨想一下是不是 server 端回收了这个 socket,因此在 client 端怎么都写入不进去. 还有就是 php 在读取消息的时候,出现消息过长的情况,那么就要考虑EOF终止符的问题了… 单次 http 每一次请求都是全新的代码, 不用自己考虑 gc 的问题, 但是在常驻内存的时候,这些就是一个个的大坑了

mysql has gone away

产生这个错误的主要原因是 mysql server 端断开了链接, client 端还拿着这个句柄去请求,解决方式有两种:

  1. show global variables like '%timeout'; 查看 wait_timeout 的时长,适当的调长一点, 这种方法治标不治本,而且有隐患 mysql> set global wait_timeout=10; mysql> show global variables like 'wait_timeout';
  2. 使用 mysql 之前需要 mysql_ping() 一下, 如果出现断开的错误就启动重连机制

js 和 php 交互传中文参数的编解码问题

之前碰到了问题是:

在 php 端 urlencode 的值为:

代码语言:javascript
复制
orderid%3D21111111110001954%26pid%3D257742%26reason%3D%E4%B8%AA%E4%BA%BA%E6%96%B9%E9%9D%A2%E5%8E%9F%E5%9B%A0_%E4%BD%BF%E7%94%A8%E7%BA%A2%E5%8C%85%E9%87%8D%E6%96%B0%E4%B8%8B%E5%8D%95%26token%3D041d9e5575f480b7bfd58b09bd14ab1c7ee9e9594f2fcdb9f0e3e39fc634b48f

需要 urldecode 一次

而在 js 端的结果是:

代码语言:javascript
复制
orderid%3D21111111110002170%26pid%3D257742%26reason%3D%25E4%25B8%25AA%25E4%25BA%25BA%25E6%2596%25B9%25E9%259D%25A2%25E5%258E%259F%25E5%259B%25A0_%25E4%25B8%25AA%25E4%25BA%25BA%25E8%25BA%25AB%25E4%25BD%2593%25E5%258E%259F%25E5%259B%25A0%26token%3D041d9e5575f480b7bfd58b09bd14ab1c7ee9e9594f2fcdb9f0e3e39fc634b48f

需要 urldecode 两次

查阅资料后:

代码语言:javascript
复制
在后端是PHP程序的情况下,保持前端Javascript和PHP之间传值的统一编码可以使用以下函数进行处理:
 
WEB前端JavaScript
 
编码:escape(encodeURI(string))
 
解码:unescape(decodeURI(string))
 
WEB后端Php
 
编码:urlencode(string)
 
解码:urldecode(urldecode(string))

为什么要encodeURI(url)两次才不会出现乱码?

PHP中rawurlencode和urlencode、JS中encodeURI与encodeURIComponent 的区别

rawurlencode遵守是94年国际标准备忘录RFC 1738

urlencode实现的是传统做法,和上者的主要区别是对空格的转义是’+’而不是’%20’

javascript的encodeURL也是94年标准,而javascript的escape是另一种用”%xxx”标记unicode编码的方法。

推荐在PHP中使用用rawurlencode。弃用urlencode

样例

source:

超级无敌的人sadha sajdh数据样本sdls fhejrthcxzb.file.jpeg

PHP urlencode:

%E8%B6%85%E7%BA%A7%E6%97%A0%E6%95%8C%E7%9A%84%E4%BA%BAsadha+sajdh%E6%95%B0%E6%8D%AE%E6%A0%B7%E6%9C%ACsdls+fhejrthcxzb.file.jpeg

PHP rawurlencode:

%E8%B6%85%E7%BA%A7%E6%97%A0%E6%95%8C%E7%9A%84%E4%BA%BAsadha%20sajdh%E6%95%B0%E6%8D%AE%E6%A0%B7%E6%9C%ACsdls%20fhejrthcxzb.file.jpeg

Javascript encodeURI|encodeURIComponent:

%E8%B6%85%E7%BA%A7%E6%97%A0%E6%95%8C%E7%9A%84%E4%BA%BAsadha%20sajdh%E6%95%B0%E6%8D%AE%E6%A0%B7%E6%9C%ACsdls%20fhejrthcxzb.file.jpeg

Javascript escape:

%u8D85%u7EA7%u65E0%u654C%u7684%u4EBAsadha%20sajdh%u6570%u636E%u6837%u672Csdls%20fhejrthcxzb.file.jpeg

帖子原文

在前端还有个问题就是, js 的 encodeURIComponentencodeURI 都不会转换 _-.!~*'()# 这些保留字符, 而在后端的 rawurlencode 则是会转换的, 因此需要前端单独把这几个给拎出来, 如下:

代码语言:javascript
复制
"*".charCodeAt(0) // 42
String.fromCharCode(42) // *

这里有张图说的很明白

图片来源

关于出现 <U+200B> 这种 zero-width space 字符

如果出现 mb_substr 这类操作的时候, 会出现字数判断错误的问题, 这个有时候很难排查, 因为在 win 上,使用命令行或者 linux 上用 cat 命令是看不到字符间是有 <U+200B> 的, 如下:

这玩意儿出现的场景就是: 在前端输入框中输入几个字, 然后复制粘贴. 这样尽管看起来之间没有空格, 但是其中还是插入了这个字符

这个就是 zero-width space 零宽空格 , 处理的办法也很简单, 前端传值之前给过滤一下, 比如 https://stackoverflow.com/questions/7055600/u200b-zero-width-space-characters-in-my-js-code-where-did-they-come-from 或 https://codeday.me/bug/20171122/97765.html

后端 php 处理的话和这个不一样, 使用 utf-8 的处理方式, 可以参考这篇文章 特殊字符<200b><200c><200d>的删除办法与原理

替换这种编码

代码语言:javascript
复制
$value = str_replace("\xe2\x80\x8b", '', $value);
$value = str_replace("\xe2\x80\x8c", '', $value);
$value = str_replace("\xe2\x80\x8d", '', $value);

编码对照如下:

mac 设置crontab -e : “/usr/bin/vi” exited with status 1

输入以下命令

代码语言:javascript
复制
export EDITOR=vim
sudo touch /etc/crontab
crontab -e
crontab -l

把默认编辑器从 vi 改成 vim

原文

出现: The “ https://bower.herokuapp.com/packages/jquery" file could not be downloaded (HTTP/1.1 502 Bad Gateway)

yii2 更新的时候静态资源出现问题, 执行 composer global require "fxp/composer-asset-plugin:~1.4.4"

问题来源

出现: Jquery UI 1.11.4 and jquery 3.0 的版本兼容问题

这个是在部署 adminLTE + rbac 时候遇上的, 打开 /admin/menu/create 会报 Jquery UI error - f.getClientRects is not a function 错误

解决方法:

配置文件: config/web.php

代码语言:javascript
复制
...
 'components' => [
     ...
        //静态资源
        'assetManager' => [
            ...
            'assetMap' => [
                'jquery.js' => 'https://cdn.bootcss.com/jquery/2.2.4/jquery.min.js', // 
                'jquery.min.js' => 'https://cdn.bootcss.com/jquery/2.2.4/jquery.min.js',
//                'jquery.js' => '@web/js/jquery/jquery.js',
//                'jquery.min.js' => '@web/js/jquery/jquery.js',
            ],
            ...
        ],
    ...
 ]
...

把相应的 jquery 替换成 v2.2.4 解决

问题来源

macOS brew安装php7.1 以及swoole扩展

brew改版后内核集成了php, 所以可以直接安装

安装php

代码语言:javascript
复制
brew install php@7.1

按提示把

代码语言:javascript
复制
echo 'export PATH="/usr/local/opt/php@7.1/bin:$PATH"' >> ~/.zshrc
echo 'export PATH="/usr/local/opt/php@7.1/sbin:$PATH"' >> ~/.zshrc

这些放到你本地命令行配置里面, 然后生成一个软链

代码语言:javascript
复制
brew link php@7.1 --force

安装扩展就得使用pecl工具了

代码语言:javascript
复制
cd /usr/local/opt/php@7.1       # 执行完 brew link 之后就按软链的来, 这样的好处就是不用记小版本号, 路径短
pecl install swoole             # 提示 'openssl/ssl.h' file not found 就是你安装的时候别选 ssl支持就行

如果提示 No releases available for package “pecl.php.net/swoole” 参考 执行 ‘pecl install swoole’之后,遇到的一些坑 , 按提示一步步走应该没问题

安装完毕之后需要变一下配置

代码语言:javascript
复制
php -i | grep .ini
...
Loaded Configuration File => /usr/local/etc/php/7.1/php.ini     //当前加载的配置文件路径
...
cd /usr/local/etc/php/7.1

先删除 php.ini 里面第一行的 extension=swoole.so 改成这个so文件的真实路径, 推荐放到隔壁的 conf.d 目录底下

然后 php -m | grep sw 可以看一下了

安装其他扩展也是按这个路数来

出现 Connection reset by peer 报错

这是个tcp链接上的错误, 意味着 链接过程中读或者写出现异常 , 出现的原因:

  1. AB两端, A端关闭了链接, B端仍在发送, 则抛异常
  2. AB两端, A退出但没关闭链接, 则B在读的时候抛异常

排查:

  1. 先看看server端是不是对包大小进行了限制, buffer分配是否足够
  2. 是不是程序链接到上限了, 被服务器误杀
  3. 防火墙问题

Warning: preg_match() [function.preg-match]: Compilation failed: PCRE does not support \L, \l, \N, \U, or \u at

php正则匹配中文字符的时候, 使用 /^[\u4e00-\u9fa5]+$/ 这一条就会报上面的错误, 正确的写法应该是:

代码语言:javascript
复制
$str = "php编程";
if (preg_match("/^[\x{4e00}-\x{9fa5}]+$/u",$str)) {
print("该字符串全部是中文");
} else {
print("该字符串不全部是中文");
}

php preg_match 正则匹配中文

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-02-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PHP技术大全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • url 当中的参数有 &timestamp=1234567890 这样的字段会被转义成 xtamp=1234567890
  • 常驻内存时发生的事情
  • mysql has gone away
  • js 和 php 交互传中文参数的编解码问题
  • PHP中rawurlencode和urlencode、JS中encodeURI与encodeURIComponent 的区别
  • 关于出现 <U+200B> 这种 zero-width space 字符
  • mac 设置crontab -e : “/usr/bin/vi” exited with status 1
  • 出现: Jquery UI 1.11.4 and jquery 3.0 的版本兼容问题
  • macOS brew安装php7.1 以及swoole扩展
  • 出现 Connection reset by peer 报错
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档