header-bg.jpg
日常开发中的踩坑记录
发表于 2021-04-14 14:18
|
分类于 印象笔记
|
评论次数 0
|
阅读次数 34

本文记录我在日常开发中踩过的一些坑,或是容易遗忘的知识点。

JS

操作 DOM 删除节点尽量使用 innerHTML 而不使用 removeChildinnerHTML 简洁且快捷,需要注意的一点是,删除节点前要删除解除绑定过的事件。

将 DOM 元素的 innerHTML 设置为空字符串,可以释放其子元素占用的内存。

for 循环优化

当循环次数是确定的,消除循环并使用多次函数调用往往会更快。

避免与 NULL 比较

避免与 NULL 进行比较,和 PHP 一样是弱类型语言 typeof 或者 instance of 检测构造函数。

一些简单的逻辑判断,可以使用短路操作替代 if 语句,例如:

myobj && doSomething(myobj);

操作DOM的选择器与操作样式的选择器分隔开, 操作DOM能用ID尽量用ID , 所以以后少用class选择DOM, 除非是事件委托 一个页面有相同元素

尽量使用局部变量 最好不要使用全局变量 能够用局部变量缓存尽量使用局部变量缓存 一个页面最多10个以内全局

添加元素至页面时,拼接2个Button时,2个Button之间需要留空格 不然2个Button中的文字就会挤在一起,因为缩进的原因 浏览器解析会默认2个Button之间有一个空格

Math.random() 取值范围: >=0 <1 字符串转换为整型: ~~“123” === 123 //output: true
~是取反后减一, 如果是字符串类型, 永远是-1 , ~~相当于向下取整 如果操作字符串那么结果永远是0, 与floor相同效果 但是比floor更好 取0-34之间的整数:
~~(Math.random() * 34)
+“20” === 20 使用+将字符串转换为数字

textarea 获取内容 为 textarea.value 而不是 innerText

循环优化 无顺序要求时,while(l–) 比 for(;i < l; i++)更好 并且更简洁 ( l–至0时为false 所以while会停止 )

正则匹配 匹配指定字符在某字符串中出现的数量 ‘o12334owero66’.match(/o/g) //output: [“o”, “o”, “o”]
‘o12334owero66’.match(/o/g).length //output: 3
‘o12334owero66’.match(/|/g).length //output: null 竖线是关键词 需要反斜杠进行转译

setTimeout() 里不能直接调用方法: 错误写法:setTimeout( some(),123) 正确写法:setTimeout(some,123)

若直接调用 则会直接解析成调用, 那么传递参数可以用bind(this, arg) 或者加引号 亦或 将setTimeout封装在闭包中

亦或是用第三 至 N个参数进行传递 亦或是 ES6 let声明在setTime上文中

Promise.all 使用方式

let {api} = this,
  suc = true,
  [videos, counts] = await Promise.all([
      api.get(`user/${this.id}/opus`),
      api.get(`user/${this.id}/opus/count`),
  ]).catch(e => {
      suc = false;
      this.alert.err(e.message);
  });

if (suc) {
    this.videos = videos;
    this.counts = counts;
}

this.is_loading = false;

异步请求报错

提示如下:

{code: 12, name: "SYNTAX_ERR", message: "SYNTAX_ERR: DOMException 12"}

原因是 fetch 的 async 值为 false 代表同步请求,不能设置回调,例如:

xhr.onreadystatechange = function(){}

直接删除该函数,或者做个判断可解决该问题。

MySQL

text bob 类型不能加 not null 和 default
primary key 不能加 unique 因为unique也是索引。

[Err] 2013 - Lost connection to MySQL server during query
my.ini配置文件 mysqld 节点下添加max_allowed_packet = 500M
也就是配置MySQL允许的最大数据包大小,上面的500M你可以根据你的项目修改为你自己的值,只要比要导入的备份文件大就可以了。

ONLY_FULL_GROUP_BY 问题

MySQL 5.7 版本以上,对某一字段使用 group by 时,如果 order by 不是同一字段,则会报错:

Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'oa.wpoa_usermeta.umeta_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

解决方式很简单,首先查询出当前的 sql mode,运行如下语句:

SELECT @@sql_mode;

运行结果如下:

ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

打开 mysql.ini,在 [mysqld] 选项下追加如下语句:

sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

以上配置去掉了 ONLY_FULL_GROUP_BY 模式,重启 MySQL,问题即可解决。

微信公众号开发

微信 URL 配置 域名下的APP目录 后面必须跟斜杠 不然永远不会生效 wx.lcgod.com/App/

与微信连接的Api接口不能继承login类 否则微信服务器访问接口时会被重定向至登录页

Linux

/‘字符串’,vi 中搜索字符串 n 换下一个 next

换行符是 \n 而Winodw是 \r\n PHP单引号不解析转译\符号

解压zip 指令 unzip cms.zip 直接原样解压到当前文件夹 不要输出-f 这个指令会忽略目录解压出来

PHP

创建文件夹后才能 putfile mkdir(‘Addons/’. $this->name . ‘/View’,0755,true); 参考微信App/Module/ManageControl
file_put_contents(‘Addons/’ . $this->name . ‘/maintest.php’,’’);

location.href = index.php?s=foo/bar/bars location.href = /index.php/a/b/c 可以根据2种不同的地址 获取到想要的地址

框架载入视图需要return View

get_defined_constants(true)[‘user’] 获得所有自定义常量 get_defined_constants()获取所有常量 get_defined_constants(true) 分类查看所有常量

删除指定单一文件unlink()即可 删除目录 rmdir() 必须是空目录 而删除目录下的所有文件 需要自己写函数foreach删除
(可参考HDPHP组件Dir)

call_user_func_array区别 get_called_calss 获取调用自己的那个类的类名

Laravel 5.7 的一些知识点

使用DB组件查询出的数组是 collection 使用array_map(‘get_object_vars’, $data) 将其二维数组中的对象也转换为数组

使用模型 create方法进行批量添加数据时 需要设置guarded = [] 不使用timestamps 需要设置public $timestamps = false

$_POST获取不到file流 可以使用Request可以获取 AJAX提交需要设置请求头 UTF8编码格式 否则Request也无法获取

AJAX 的一些知识点

接口返回值不 json_encode 的话必须给一个指定字符串 前台根据这个字符串来判断 不给定字符串 直接判断 返回错误页面也是字符串 结果是true

上传文件 返回500状态码,报错如下:

Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException: The file does not exist in file

原因是因为 php.ini 中的允许最大上传尺寸没有那么大,修改以下配置就好了

upload_max_filesize = 2M

CSS

设置body占满整个浏览器窗口: html,body{ height:100%} 要让html元素也100% 不然设置一个没用

黑白滤镜 例如某个名人去世之后百度的网页会变成黑白的

body.memorial {
    filter: grayscale(100%);
    -webkit-filter: grayscale(100%);
    -moz-filter: grayscale(100%);
    -ms-filter: grayscale(100%);
    -o-filter: grayscale(100%);
    filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
    -webkit-filter: grayscale(1);
}

一个页面上只用到几个图标 可以用 svg 图形作为背景即可 不需要引入 iconfont

提升动画性能的小技巧

将 tranform 的一些属性设置为 3D 的方式,例如:

tranform:translate3d(0,-25%,0)

浏览器渲染以上代码时,会调用 GPU 来替代 CPU 工作,可以说这是一种 hack 小技巧吧。

Nginx

URLRewrite 本地配置也同样需要配置域名,需要配置 nginx.conf,与配置 hosts 文件

Git

git pull 失败 强行覆盖本地文件:

git fetch --all
git reset --hard origin/master
git pull

git pull 提示 fatal: refusing to merge unrelated histories 使用以下命令:

git pull origin master --allow-unrelated-histories

52 JS charAt 与 []访问字符串的区别是charAt是ES3的写法 []是ES5的写法 charAt在访问不到指定的索引时会给出’’ 而[]给出undefined
charAt兼容IE6 7 而[]不兼容

53 PHP Laravel 数据迁移报错:Syntax error or access violation: 1075 Incorrect table definition; there can be only one auto column and it
must be defined as a key 原因是无法给int类型指定长度 第二参数并不是指定长度的 而是 是否自增 而且没有添加注释的comments方法

54 OSS PHP里设置的过期时间不能太短 否则会403

55 PHP TP5 Windows环境下 Nginx设置TP5的根目录不能为小写开头 例如tp5/public会访问不到 若设置为Tp5/public则能访问到

56 PHP PHPStorm静态调用使用魔术方法会标记黄色 只需要在__callStatic的类前加上注释即可
/**
*
* @method static string make()
* @method static object with($params)
*/

57 PHP mcrypt从PHP7.0弃用 调用相关方法会报错
58 PHP 在执行 composer require "qcloud/cos-sdk-v5:>=1.0"时 会将其他依赖一起更新 解决办法是指定版本号
执行composer require "qcloud/cos-sdk-v5:1.2.3"即不会更新其他依赖
59 PHP TP3.2使用composer包 composer require之后 在入口文件的require ThinkPHP.php之前 require ./vendor/autoload.php即可
60 PHP ISO 8601 扩展格式 YYYY-MM-DDTHH:mm:ss:sssZ 例如:2018-01-01T00:00:00 (只有兼容ECMAScript 5的才支持这种格式)
将以上格式与简单格式互换 date(‘Y-m-d H:i:s’, strtotime(‘2018-06-06T09:27:01.000Z’))
即先使用strtotime将其转换为时间戳 再格式为简单时间 以上代码输出为 2018-06-06 17:27:01
61 JS 当一个元素 内部HTML发生改变时, JQ绑定的委托事件不会失效 而原生JS的委托会失效 当一个元素外部HTML发生改变时 JQ JS都会失效
62 JS 去除字符串最右边的 字符串 ‘/’ 可以使用lastIndexOf取得下标后 使用substr(0, index) 即可去除该字符串 此方法类似于PHP的rtrim
63 MySQL 查询时出现this is incompatible with sql_mode=only_full_group_by 是因为5.7版本设置了sql_mode为full_group_by模式
意思是出一条SQL语句中 查询的字段必须包含在 group by内 否则无法使用group by
解决这个问题的方法也很简单 在my.ini里更改mysqld的选项如下
[mysqld]
sql_mode =‘STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION’
增加以上配置后即不会出现报错
另外Laravel框架: config/database.php 选项’strict’ => false 才会关闭严格模式, 所以使用laravel也需要设置该配置
64 MySQL 主从复制 从服务器出现以下报错
Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file
原因是因为指定的master_log_file='mysql-bin.000001’文件名称书写输错 mysql-bin000001
解决方案 stop slave; change master to master_log_file=‘mysql-bin.000001’; start slave;
65 Nginx ./configure: error: perl module ExtUtils::Embed is required
66 Nginx SH脚本 no such file 因为编码问题 重新从线上下载一份脚本至本地即可
67 Mysql server has gone away 导入大文件出错 设置 max_allowed_packed=999M
68
laravel数据库查询返回的数据不是单纯的数组形式, 而是数组与类似stdClass Object这种对象的结合体,
即使在查询构造器中调用了toArray(), 也无法转换成单纯的数组形式。

Laravel5.4开始不再支持在配置文件中定制PDO的fetch mode, 取而代之的是
总是使用PDO::FETCH_OBJ, 如果你仍然想要为应用定制fetch模式, 需要监听新的Illuminate\Database\Events\StatementPrepared事件

首先打开app/Providers/EventServiceProvier.php 引入Illuminate\Database\Events\StatementPrepared类:

use Illuminate\Database\Events\StatementPrepared;

然后在boot方法中加入如下代码:

Event::listen(StatementPrepared::class, function ($event) {
$event->statement->setFetchMode(\PDO::FETCH_ASSOC); //这里我们使用PDO::FETCH_ASSOC
});

这样我们就大功告成啦, 现在你的laravel数据库查询返回的数据就是单纯的数组形式
69 Laravel Dingo controllers/Api目录自带api前缀 env中的API_PREFIX不能设置为api 如果设置了api会报错400
同时如果没有设置API_DOMAIN 则API_PREFIX必须设置为api以外其他值 API_DOMAIN与API_PREFIX二选一

70 Mysql 统计技巧: 若想在统计的同时查询其他字段 可以在count中加入or null条件 或者 用sum统计: select count(a=1 or null) from table; sum(a=1)有同样效果

71 JS Vue-element-ui 分页样式 选中状态总是为1 无法改变 原因是因为改变了统计数量 如果改变了统计数量 就必须再选中一次 所以解决方案就是
在改变总数后, 改变一次选中页码即可

72 PHP Composer安装报错: php_bz2.dll (找不到指定的模块。
解决方案: 检查PHPStudy php_bz2.dll扩展是否开启
检查运行composer.exe时 选择的php.exe是否路径正确
检查php.ini中的extension_dir路径是否正确

73 Laravel 查看代码执行过的sql语句:

DB::enableQueryLog();// 开启数据记录

$userId = DB::table(‘users’)->where(‘proto_id’, 19053)->value(‘id’) ?: 0;
var_dump($userId);
DB::table(‘users’)->where(‘proto_id’, 19053)->value(‘id’)

return response()->json(DB::getQueryLog());// 获得sql语句 在页面中即可看到执行了2条sql

74 SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client
是因为MySQL8的密码模式问题 升级mysql8后 需要修改如下:
windows修改my.ini Linux修改my.cnf 增加如下配置项
default_authentication_plugin=mysql_native_password
update user set host=‘127.0.0.1’ where user=‘root’ and host=‘localhost’ limit 1;

75 PHP Laravel中使用JWT 对任意数组创建token报错
payload does not contain the required claims

使用如下方式即可
$customClaims = [‘sub’ => [
‘foo’ => ‘bar’
]];
$payload = JWTFactory::customClaims($customClaims)->make();
$token = JWTAuth::encode($payload);

解码方式:
JWTAuth::setToken($token)->getPayload()->get(‘sub’) //结果:[‘foo’ => ‘bar’]

76 explain select id, title, thumb, view, concat(‘http://www.vhiphop.top/video/’, id) as link from videos
where status = 1 and is_local = 1 and reco != 1 and studio_id = 2 order by addtime desc limit 10 offset 10;
该语句where 与 order by 的列不是一个 所以当没有建立索引时会显示using file sort 优化方案:
在addtime , reco

78 Mysql 随机数
select * from videos as a join (select round(rand() * ((select max(id) from videos)-(select min(id) from videos))+(select min(id) from videos)) as id) as b where a.id >= b.id order BY a.id limit 1;

79 JS 判断对象是否为空
JSON.stringify(obj) === ‘{}’ !!Object.keys(obj).length

80 用$post变量接收Request对象时 如果前端传了一个空对象, 在浏览器是显示为空字符串的 而PHP是null类型 所以判断元素是否存在 需要使用 !empty 而不是 isset 因为isset无法判断为Null

81 Laravel 返回数据时 若使用terminate中间件 不能提前die掉 否则会直接结束生命周期 所以需要echo 或者 return
并且返回时 不能直接使用http_response_code()函数设置状态码(例如204) 因为Laravel会将状态码始终处理为200
所以需要使用Laravel自带的方法 return response()->json([], 204) 来处理状态码

82 Nginx 启动nginx时报错 nginx -t 如下
[root@vhiphop www]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: [emerg] mkdir() “/var/tmp/nginx/client_body” failed (2: No such file or directory)
nginx: configuration file /etc/nginx/nginx.conf test failed

于是输入命令行:
mkdir -p /var/tmp/nginx/client_body

成功运行
[root@vhiphop nginx]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@vhiphop nginx]# service nginx reload
Reloading nginx configuration (via systemctl): [ OK ]

83 PHP curl 死活POST请求微博第三方登录的接口 一直是一个400 Nginx 错误页面 经过几个小时的测试 百度 谷歌… 终于发现问题所在
之前请求地址都是 POST方式请求 后面跟一堆参数 https://api.weibo.com/oauth2/access_token?client_id=&…
这种方式在本地访问是没有任何问题的 但是在服务器上就一直有上述问题
所以掉坑之后 把查询参数改为body方式 才从坑里爬出来…

请求地址:
https://api.weibo.com/oauth2/access_token

curl 中加上POST参数:
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
‘client_id’ => 123456,
‘client_secret’ => ‘123456’,
‘grant_type’ => ‘authorization_code’,
‘redirect_uri’ => ‘http://www.vhiphop.com/login/qq-callback.php’,
‘code’ => ‘123456’
]));

然后就大功告成了

84 PHP php-fpm平滑重启:
kill -USR2 cat /usr/local/php/var/run/php-fpm.pid

查看php-fpm进程数
ps aux | grep -c php-fpm
查看所有进程 第一个为用户 第二个为进程号
ps aux |grep php-fpm

85 Linux stat abc.php 可以查看文件修改时间

86 PHP opcache缓存清空 需要php.ini的配置validate为1的时候才会被清空
opcache.validate_timestamps=1
否则即使重启php-fpm也无法清空缓存 注意: nginx是不需要重启的

87 PHP setcookie() 此函数的原理是 使响应头携带set-cookie标识 让浏览器设置cookie (set-cookie相关信息在MDN里有介绍)
Chrome不能查看到此cookie相关信息 而使用Firefox可以查看到
如果PHP不设置cookie的作用域 那么该cookie的作用域是Referer下的所有域名 例如Referer是: http://vhiphop.com/sign/up
那么作用域就是http://vhiphop.com/sign/ 后面以该前缀开头的Referer请求服务器时都会携带set-cookie设置的信息
如果是 http://vhiphop.com/user (不是…sign开头) 则浏览器请求服务器时不会携带该cookie

88 PHP Laravel 使用$request->fullurl() 获取到的参数始终多出一个s=video/1之类的参数 排查之后发现是nginx的配置问题

URLRwrite

location / {
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=$1 last;
break;
}
}
很明显的一个问题地址上多了个s=$1 这个是TP的nginx重定向配置 当时安装laravel时直接复制了过来就没看 而真正laravel的重定向如下:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
修改后再使用$request->fullurl() 获取到的地址就是正确的完整地址了

89 MySQL SQL报错:
Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column
‘hiphop.a.id’ which is not functionally dependent on columns in GROUP BY clause;
this is incompatible with sql_mode=only_full_group_by

原因是因为orderBy的字段 不是groupBy的字段 并且groupBy的字段不是主键

解决方案: (1)使用any_value()将查询字段包起来 example: select any_value(a.id) from table group by stu_id;
(2)更改mySQL的only_full_group_by

88 前端游戏领域知识储备:
alloy team骨骼动画 box2d js碰撞检测 cocos2dx粒子编辑器 高性能渲染机制
createJs egret
three.js(绝对优势) cocos2d-js(绝对优势)

89 MySQL 字符 char(20) 表示20个字符 无论中文还是英文都能储存20个字符 JS的.length检测的长度与MySQL一致
而PHP的str_len检测的是字节 一个UTF格式的汉字占3个字节 所以PHP要和MySQL JS保持一致需要使用mb_strlen

90 Linux 开启root用户远程密码登录
sudo passwd root
sudo vi /etc/ssh/sshd_config
PermitRootLogin no改为yes
PasswordAuthentication no改为yes
sudo systemctl restart sshd

91 Linux 查找文件
whereis filename

92 yum 安装PHP7.3
卸载旧版本
yum -y remove php*
更新yum源
rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

查看包
yum list | grep php

安装指定版本
yum install -y php73-php php73-php-fpm php73-php-mysql php73-php-curl php73-php-gd php73-php-mbstring php73-php-xml php73-php-xmlrpc php73-php-zip php73-php-opcache

查看安装好的包
yum list installed |grep php

查看状态
PHP -v
systemctl status php73-php-fpm.service
systemctl start php73-php-fpm.service
systemctl restart php73-php-fpm.service

93 Linux 查看系统操作位数
getconf LONG_BIT

64 Linux 查找文件 find / -name php

65 Linux 执行crontab
*/30 * * * * flock -xn /tmp/abc.lock -c ‘/opt/remi/php73/root/usr/bin/php /home/www/read.php >> /home/www/cron.log 2>&1’
以上命令避免重复执行
不用绝对路径 ‘php read.php >> /home/www/error.log’ 会提示
/bin/sh: php: command not found
用了绝对路径又会在PHP文件里报错, 所以直接在PHP文件开头引入, 这样就可以使用相对路径了
chdir(dirname(FILE));

查看crontab执行情况
tail -f /var/log/cron
systemctl status reload restart crond

66 MySQL将一个表的统计数量导入到另一张表的一个字段中
update videos as a join (select video_id, count(1) as num from comments group by video_id) as b on a.id = b.video_id set a.comments = b.num;

67 MySQL格式化时间
date_format(a.add_time, ‘%Y-%m-%d %H:%i’) as add_time

68 设置开图广告

[root@vhiphop ~]# /usr/local/redis/bin/redis-cli
127.0.0.1:6379> get osAdvert
“{“thumb”:“https://h5.youzan.com/v2/goods/26yz0wxbbs136”,“link”:“https://img.vhiphop.top/admin/advert/mt-pop.jpg”}”
127.0.0.1:6379> set osAdvert ‘’
OK
127.0.0.1:6379>

70 MySQL 查询时间格式化 date_format(a.addtime, ‘%Y-%m-%d %H:%i’) as addtime

PHPStorm

配置 24G内存

-server
-Xms384m
-Xmx6144m
-XX:ReservedCodeCacheSize=512m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-Djdk.http.auth.tunneling.disabledSchemes=""
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow

主题丢失时从c盘用户文件中导入即可

标记错误时 可以使用alt + enter解决

提示 ext-json is missing in composer.json
打开 Setting -> Editor -> Inspections -> PHP -> Composer 把勾去掉

连接 MySQL 提示 java.lang.RuntimeException: com.mysql.cj.exceptions.InvalidConnectionAttributeException

把连接地址加上查询参数即可

jdbc:mysql://127.0.0.1:3306/database_name
?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

发布评论
还没有评论,快来抢沙发吧!