〓 系统
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 关机 | halt | halt | |
| 重启 | reboot | reboot | |
| 系统监视器 | top | 系统时间, 运行天数, 当前登录用户数, 系统负载 总进程数, 运行中的, 睡眠的, 停止的, 未响应的 Cpu(s):us 用户, sy 系统, ni XX, id 空闲, wa 等待, hi XX, si XX Mem, 已使用, 空余, 缓冲 Swap, 已使用, 空余, 缓冲 快捷键: M 按占内存排序 P 按占Cpu排序 1 显示每个 Cpu k 杀死进程 q 退出 | top |
| 查看进程 | ps | aux -ef | 列出包含 java 的进程 ps aux |grep java ps -ef |grep java |
| 查看内存及 Swap 用量 | free | -b,-k,-m,-g 按单位显示 | free -m |
| 查看系统时间 | date | 显示 CST 时间 -R 显示时区 -u 显示 UTC 时间 | date |
| 查看硬件时间 | clock | clock | |
| 设置系统日期 | date -s 月/日/年 | ||
| 设置系统时间 | date -s 时:分:秒 | ||
| 将系统时间写入到硬件时间 | clock -w | ||
| 查看系统版本 | cat /etc/*release | ||
| 升级系统软件 | yum update -y |
〓 文件
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 进入目录 | cd | cd .. # 上一层目录 cd /root # 根目录 | |
| 列出目录 | ls | 白色:表示普通文件 蓝色:表示目录 绿色:表示可执行文件 红色:表示压缩文件 浅蓝色:链接文件 红色闪烁:表示链接的文件有问题 黄色:表示设备文件 灰色:表示其他文件 | ls |
| 创建目录 | mkdir | mkdir XXX | |
| 删除目录 | rm | rm -rf XXX | |
| 删除文件 | rm | rm XXX | |
| 复制文件 | cp | cp XXX YYY | |
| 复制目录 | cp | -r 复制目录及目录内的所有项目 -v 详细显示进行的步骤 | cp -rv XXX YYY |
| 重命名文件 | mv | -i: 若指定目录已有同名文件,则先询问是否覆盖旧文件; -f: 在mv操作要覆盖某已有的目标文件时不给任何指示; | mv 源文件 目标文件 |
| 移动文件 | mv | mv 一个或多个文件 目标目录 | |
| 下载文件 | wget | 下载到当前目录 | wget http://XXX.tar.gz |
| 计算文件/目录的磁盘用量 | du | -a 不仅显示目录,同时显示文件 -h 容易阅读方式显示 --max-depth=N 可指定计算深度 | du -ah --max-depth=1 | sort -n |
| 查找文件 | find | find /home -name *.apk |
〓 tar
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| tar | tar | -z 是否压缩 -c 打包 -x 解包 -v 详细地列出处理的文件 -f | 打包:tar -cvf abc.tar abc 解包:tar -xvf abc.tar 压缩打包:tar -zcvf abc.tar.gz abc 解压解包:tar -zxvf abc.tar.gz |
〓 磁盘
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 查看所有磁盘及分区 | fdisk -l | fdisk -l | |
| 查看当前挂载 | df | -h 按可阅读的方式打印数值和单位 -T 显示文件系统类型 | df -hT |
| 管理磁盘分区 | fdisk /dev/*** | 进入后的操作说明: m 显示命令菜单 d 删除一个分区 n 创建一个分区(e 扩展分区;p 主分区) t 改变分区ID q 不保存退出 w 保存退出 | fdisk /dev/vdb |
| 格式化分区 | mkfs.*** /dev/***N | mkfs.xfs /dev/vdb1 | |
| 挂载分区 | mount /dev/***N /*** | mount /dev/vdb1 /www | |
| 卸载分区 | umount /dev/***N | umount /dev/vdb1 | |
| 开机自动挂载 | vi /etc/fstab | 配置文档格式:设备 挂载点 文件系统类型 defaults 0 0 | 打开:vi /etc/fstab 配置:/dev/vdb1 /www xfs defaults 0 0 |
〓 网络
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 查看 IP 配置 | ifconfig | ifconfig | |
| 配置网卡 IP | 配置文件目录:/etc/sysconfig/network-scripts/ 配置文件格式: DEVICE=eth0 / eth0:0 / ... # 在配置多线时若使用 cp 命令复制配置文件,必须修改此项以防止冲突 HWADDR=XX:XX:XX:XX:XX:XX # 网卡地址 TYPE=Ethernet # 以太网 UUID=******** ONBOOT=yes # 开机启动 NM_CONTROLLED=yes BOOTPROTO=static # 使用静态 IP IPADDR=192.168.1.2 # IP 地址 NETMASK=255.255.255.XXX # 子网掩码 GATEWAY=192.168.1.1 # 网关 DNS1=114.114.114.114 DNS2=8.8.8.8 | vi ifcfg-XXXN(:N) | |
| 重启网卡 | 使配置生效 | service network restart |
〓 防火墙
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 配置 iptables | 添加需要允许的端口的方法同 22 端口 | vi /etc/sysconfig/iptables | |
| 重启使配置生效 | service iptables restart |
〓 用户/权限
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 添加用户 | useradd | -g 组名 # 加入到该组 -s /bin/false #不允用户直接登录系统 | useradd –g 组名 用户名 -s /bin/false |
| 修改密码 | passwd | passwd 用户 | |
| 查看所有用户 | cut -d : -f 1 /etc/passwd | ||
| 查看可以登录系统的用户 | cat /etc/passwd | grep -v /sbin/nologin | cut -d : -f 1 | ||
| 删除用户 | -r, --remove remove home directory and mail spool | userdel 用户 | |
| 添加用户组 | groupadd | groupadd 组名 | |
| 为组添加用户(用户必须已存在) | gpasswd | gpasswd -a 用户 组 | |
| 将用户移出组 | gpasswd | gpasswd -d 用户 组 | |
| 查看用户所属组 | groups | groups 用户 | |
| 查看组中有哪些用户 | groupmems | groupmems -g 组 -l | |
| 更改文件/目录所有者 | chown | -R 递归处理所有的文件及子目录 | chown -R 用户:组 *** |
| 更改文件/目录权限 | chmod | -R 以递归方式更改所有的文件及子目录 | chmod -R 777 *** |
〓 vi 编辑器
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 打开文件 | vi | vi XXX | |
| 进入编辑模式 | 按 a/i/o/Insert 等 | ||
| 进入末行模式/命令模式 | 按 Esc后: :w 保存不退出 :q 退出(提示是否保存) :wq 保存并退出 :w XXX 另存到文件 XXX :q! 不保存退出 |
〓 计划任务
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 设置计划任务 | crontab | 详细步骤见本页底部 | crontab -l # 查看计划任务 crontab -e # 编辑计划任务 |
〓 网站
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 简单审查日志 | cat | grep | cat 日志文件 | grep 关键词1 | grep 关键词2 | more | |
| 日志分析 | goaccess | 见下文 |
〓 goaccess
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 安装 | yum install goaccess | ||
| 日志格式 | NCSA Commbined Log Format | date_format %d/%b/%Y log_format %h %^[%d:%^] "%r" %s %b "%R" "%u" | |
| 参数 | -f | 需要解析的日志文件 | |
| 参数 | -e | 指定 IP 地址统计 | |
| 参数 | -p | 指定配置文件 | 可以将上面的日志格式内容保存到文件 ~/.goacessrc |
| 参数 | -H | 显示 HTTP 协议信息 | |
| 参数 | -M | 显示 HTTP 方法信息 | |
| 生成文件 | goaccess -f 日志文件 -p ~/.goaccessrc > 目标文件.htm |
〓 lnmp
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 重启 LNMP | /root/lnmp restart | ||
| 重启 MySQL | /etc/init.d/mysql restart | ||
| 重启 PureFTPd | /root/pureftpd restart | ||
| 安装 LNMP | http://lnmp.org/install.html | ||
| 常见问题 | http://lnmp.org/faq.html | ||
| 状态管理命令 | http://lnmp.org/faq/lnmp-status-manager.html | ||
| 相关软件目录及文件位置 | http://lnmp.org/faq/lnmp-software-list.html | ||
| 防跨站、跨目录安全设置(仅支持 PHP 5.3.3 以上版本) | http://www.vpser.net/security/lnmp-cross-site-corss-dir-security.html | ||
| 查看 Nginx 版本 | nginx -V | ||
| 查看 MySQL 版本 | mysql -V | ||
| 查看 PNP 版本 | php -v | ||
| 查看 Apache 版本 | httpd -v | ||
| 查内存 | cat /proc/meminfo | ||
| php.ini | vim /usr/local/php/etc/php.ini | ||
| MySQL 配置文件 | vim /etc/my.cnf | ||
| 添加网站 | /root/vhost.sh | ||
| 添加 ProFTPd 用户 | /root/proftpd_vhost.sh |
〓 nginx
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 启动/停止/重启 | service nginx 或 /etc/rc.d/init.d/nginx | service nginx start service nginx stop service nginx restart | |
| 伪静态 | 在 .conf 文件中配置 | rewrite ^(.*)/read-htm-(.*)\.html(.*)$ $1/read.php?$2.html? last; rewrite ^(.*)/thread-htm-(.*)\.html(.*)$ $1/thread.php?$2.html? last; rewrite ^(.*)-htm-(.*)$ $1.php?$2 last; rewrite ^(.*)/simple/([a-z0-9\_]+\.html)$ $1/simple/index.php?$2 last; rewrite ^(.*)/data/(.*)\.(htm|php)$ 404.html last; rewrite ^(.*)/attachment/(.*)\.(htm|php)$ 404.html last; rewrite ^(.*)/html/(.*)\.(htm|php)$ 404.html last; | |
| 防盗链 | 在 .conf 文件中配置 | HttpRefererModule | location ~* \.(gif|jpg|png|swf|flv)$ { valid_referers none blocked *.0574bbs.com *.eyuyao.com 0574bbs.com eyuyao.com; if ($invalid_referer) { rewrite ^/ http://web1.eyuyao.com/yyad/src/3122.jpg; # return 404; } } |
| 浏览器缓存 | 在 .conf 文件中配置 | location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } |
〓 vsftpd
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 安装 | yum install vsftpd | ||
| 查看是否已安装 | rpm -q vsftpd | ||
| 启动/停止/重启 | service vsftpd | service vsftpd start service vsftpd stop service vsftpd restart | |
| 配置文件 | vi /etc/vsftpd/vsftpd.conf |
〓 MySQL
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 登录 | mysql | mysql -u username -p | |
| 登出 | exit | ||
| 查看信息 | status; | ||
| 查询当前正在执行的 SQL 语句 | show processlist; | ||
| 删除指定时间之前的日志 | PURGE | PURGE MASTER LOGS BEFORE '2015-1-1 0:00:00'; |
〓 scp 远程文件/目录传输命令 (yum install openssh-clients) 用法
scp 会把文件权限(读取/写入/执行)带过来,但所有者为当前执行 scp 命令的用户。
scp 低版本有许多漏洞,用完最好 yum remove openssh-clients
scp 采用直接覆盖的机制,如需判断文件无差异则跳过,应改用 rsync 命令。查看 rsync 详细使用方式及与 scp 对比
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 若远程服务器 SSH 端口非默认 | scp | -P 端口号 | |
| 下载远程服务器上的文件到本地 | scp | scp 远程用户@远程服务器:远程文件 本地文件 | |
| 下载远程服务器上的目录到本地 | scp | -P 端口 -v 显示进度 -r 递归 | scp -r 远程用户@远程服务器:远程目录 本地目录 实例:scp -r root@x.x.x.x:/a/b/ /c/d/ 结果:/c/d/b/,即将整个 b 复制到 d 下(注意与 rsync 命令的区别) |
| 将本地文件上传到远程服务器 | scp | scp 本地文件 远程用户@远程服务器:远程文件 | |
| 将本地目录上传到远程服务器 | scp | 最终目录结构参:远程->本地 | scp -r 本地目录 远程用户@远程服务器:远程目录 |
〓 rsync 远程文件/目录传输命令 (yum install rsync) 用法查看 rsync 详细使用方式及与 scp 对比
rsync 会把文件权限(读取/写入/执行)带过来,所有者也会带过来。
相比于 scp 最大的优势就是可以增量同步
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 下载远程服务器上的目录到本地 | rsync | -a 递归 -v 详细 -p, -- perms 保持权限 -g, -- group 保持属组 -o, --owner 保持属主 -r 递归 --progress 打印 --delete 删除已不存在的文件 -u 表示仅更新较新的文件 -z 表示在传输过程中进行压缩 -e 'ssh -p 2222' 指定其它端口 | rsync 远程用户@远程服务器:远程目录 本地目录 实例:rsync -avu --progress root@x.x.x.x:/a/b/ /c/d/ 结果:/c/d/,即将 b 内的文件(夹)复制到 d 下(注意与 scp 命令的区别) |
| 将本地文件上传到远程服务器 | rsync | rsync 本地文件 远程用户@远程服务器:远程文件 | |
| 将本地目录上传到远程服务器 | rsync | 最终目录结构参:远程->本地 | rsync 本地目录 远程用户@远程服务器:远程目录 |
〓 ftp 客户端 (yum install ftp)
| 功能 | 命令 | --help | 示例 |
|---|---|---|---|
| 登录 | ftp | ftp 目标服务器 | |
| 列出远程当前路径目录/文件 | ls | ls | |
| 创建远程目录 | mkdir | mkdir 目录名 | |
| 删除远程目录(空) | rmrmdir | mkdir 目录名 | |
| 进入远程目录 | cd | cd 目录名 | |
| 显示远程当前路径 | pwd | pwd | |
| 重命名远程文件 | rename | rename 原文件名 新文件名 | |
| 上传文件 | put | put 本地文件名 | |
| 下载文件 | get | get 远程文件名 | |
| 批量下载文件 | mget | 需要单个确认 | |
| 批量下载文件【lftp】 | mirror | 参数有很多 | mirror |
| 返回 shell(不退出) | ! | ! | |
| 返回 ftp(接上步) | exit ftp | exit ftp | |
| 结束 | bye quit | bye quit |
〓 iftop
流量监控工具 教程
〓 GoAccess
实时网站日志分析工具 官网
〓 Cacti
常见问题笔记
加硬盘
插入新硬盘
若有 RAID,则先设置,使操作系统能认到硬盘
使用 fdisk 命令对新设备进行分区
使用 mkfs 命令对新分区进行格式化
使用 mount 命令进行挂载
设置开机自动挂载(vi /etc/fstab)
更改 MySQL 数据库目录位置
停止 MySQL 服务
将原数据目录转移或复制到新位置(若是复制,则修改所有者使原来一致)
找到 my.cnf 配置文件(一般在 /etc/),修改 datadir 值为新路径
启动 MySQL 服务
502 Bad Gateway 问题排查
查看 PHP 日志,路径:/usr/local/php/var/log
一般为“server reached pm.max_children setting (10), consider raising it”连接数问题,在“/usr/local/php/etc”下的所有配置文件中查找并修改相关设置即可(如改成 1000)。
计划任务(实例:定时备份数据库并通过 FTP 同步至其它服务器)
创建可执行文件:vi dotask.sh
dotask.sh 的内容示例:
DATE_TIME=`date +%Y_%m_%d_%H%M%S`;
FILE_NAME=数据库名_backup_$DATE_TIME.sql;
cd /home/mysqlbackup/;
mysqldump -u数据库用户名 -p数据库密码 数据库名>$FILE_NAME;
tar -zcf $FILE_NAME.tar.gz $FILE_NAME;
rm $FILE_NAME;
ftp -v -n FTP地址 << END
user FTP用户名 FTP密码
bin
put 本地目录文件 目标路径文件
bye
END
文件名乱码问题可以在行末加“;”来解决赋予执行权限:chmod 777 dotask.sh (ls 命令时呈绿色)
编辑计划任务:crontab -e
crontab 书写规则:
# 分 时 日 月 周 文件路径
0 3 * * * /home/dotask.sh
30 4 * * * /home/dotask2.sh重启 crond:/etc/init.d/crond restart
netstat
netstat -an | grep xxx.xxx.xxx.xxx 可查看此 IP 的 TCP 请求及端口
论坛使用阿里云的 ECS + RDS + OSS 搭建,最近经常隔三差五出现 RDS 的 CPU 和连接数突然满负荷的情况,导致数据库无法连接。这种情况一般会认为是受到了攻击,因为如果是访问量大或者是哪里有慢查询,应该是资源消耗逐步上升直至崩溃的,沿着这个思路去查 Web 日志封 IP,但效果不大,关闭功能、卸载插件也没用。
开启阿里云后台的 SQL 审计,能看到 SQL 查询日志,但是很难找有问题的 SQL。
最终在重启 RDS 后执行以下语句列出所有正在执行或阻塞的语句:
show full processlist在结果列中,Command 为 Query 是正在执行查询操作的语句,发现几乎所有的 SQL 都是:
SELECT * FROM pre_forum_thread WHERE tid>0 AND fid IN('42','95','247','41','567','62','149','229','37','230','93','190','284','75','38','568') AND `fid`<>'546' AND replies > 0 AND displayorder>=0 ORDER BY lastpost DESC LIMIT 10再加上之前出现的情况是,论坛帖子列表和详情页面能正常打开时,论坛首页也不一定能打开,所以基本定位到是“首页四格”的数据库查询导致的。
进入论坛后台首页四格设置,对比了版块 id 后确认了这个 bug。
单独执行该语句大约耗时 5s(主题帖 200 万),设置的缓存时间 10 分钟。
processlist 中看到这些语句的 state 都是 Creating sort index,尝试去掉 ORDER BY 后执行果然只需要 16ms。
5s 内的访客都是从数据库读取的,能处理完就正常,否则累积就导致 RDS 崩溃,每 10 分钟都会重现一次风险。
当然这个问题可以通过添加索引来解决。
收录了一些个人觉得不错的网页开发插件。
由于插件更新频繁,本页如有错误请指正,也欢迎告知更多功能强大、使用方便的插件。
| 插件 | 简介 | 备注 |
| 框架 | ||
| jQuery | 最流行的 JS 框架 | 下载、中文文档、英文整合文档、中文整合文档,浏览器支持、来自 css88 的文档 官方建议 IE 6-8 使用 1.12.4 |
| Angular、中文版 AngularJS (version 1.x) | 一套框架,多种平台同时适用手机与桌面 | MVC 架构,使得开发现代的单一页面应用程序(SPAs:Single Page Applications)变得更加容易 |
| Vue.js | 是一套用于构建用户界面的渐进式框架。 | |
| Bootstrap、中文版 | 简洁、直观、强悍的前端开发框架 | 英文文档、v3中文文档、v2中文文档、视频教程,主题和模板 |
| jQuery UI | 为 jQuery 提供更丰富的功能 | 示例:Datepicker、Color Animation、Shake Effect |
| 功能 | ||
| jQuery File Upload | jQuery 文件上传 | 英文文档 |
| jQuery Cookie | 读取、写入和删除 cookie | 浏览器支持,文档 |
| json2.js | json 操作库 | 已弃用,旧 IE 用 jQuery 的 parseJSON,HTML 5 用 JSON.parse |
| Lightbox | 老牌图片浏览插件 推荐使用更强大的 Viewer.js | |
| Swiper、中文版 | 最现代的移动触摸滑块(Most Modern Mobile Touch Slider) | 英文文档,中文文档,旧浏览器支持版本:2.x.x,Swiper 2 英文文档,中文文档 |
| jquery-cropper | 图片裁剪 | |
| FastClick | 用于消除手机浏览器上触摸事件触发之间的 300 毫秒延迟 | 用法,不应用的场景 |
| PACE | 页面加载进度条 | 文档,IE8+ |
| toastr | jQuery 通知 | 文档 |
| Autosize | 一款小巧的,可自动调整 textarea 高度的独立脚本 | IE9+ |
| X-editable | 允许您在页面上创建可编辑元素 | 文档,Demo |
| select2 | 一款提供搜索过滤、自定义样式的下拉框插件 | |
| jQuery Tags Input | 标签输入框 | 用法 |
| Viewer.js | 图片浏览插件 | GitHub(viewerjs)、GitHub(jquery-viewer) jquery-viewer 是 viewerjs 的 jQuery 插件,即在 jQuery 环境中要同时引用这两个脚本。 |
| PDF.js | A general-purpose, web standards-based platform for parsing and rendering PDFs. | |
| 编辑器 | ||
| UEditor | 百度在线编辑器 | GitHub 下载、文档、ASP.NET 部署教程 |
| 日期时间 | ||
| bootstrap-datepicker | Bootstrap 日期选择器 | Online Demo |
| DateTimePicker | 日期时间选择 | |
| MultiDatesPicker | 多日期选择 | |
| FullCalendar | 日历日程事件工作表 | IE 9+, jQuery 2.0.0+ |
| TimeTo | 计时、倒计时 | |
| 图表 | ||
| D3.js | D3.js 是基于数据驱动文档工作方式的一款 JavaScript 函数库,主要用于网页作图、生成互动图形,是最流行的可视化库之一。 | |
| Highcharts、中文版 | 兼容 IE6+、完美支持移动端、图表类型丰富、方便快捷的 HTML5 交互性图表库 | 文档 |
| ECharts | 百度图表控件 | |
| AntV | 来自蚂蚁金服的专业、简单、无限可能的可视化解决方案 G2 - 专业易用的可视化类库 G2-mobile - 移动端高性能可视化类库 G6 - 关系图可视化类库 | 流程图, 关系图, 可视化规范, 地图, 河流图, 力导图, 网络图, UML图, 业务流程图, 时序图 |
| SyntaxHighlighter | 功能齐全的代码语法高亮插件(JS) | |
| 动态排名数据可视化 | 将历史数据排名转化为动态柱状图图表 开源代码,非插件,修改使用 | GitHub、视频教程、EV录屏、网页示例、视频效果 |
| 图标 | ||
| Font Awesome | 完美的图标字体 | IE 8+,v3.2.1 支持 IE 7,进阶用法(定宽/边框/动画/旋转/叠加) |
| Glyphicons | 图标字体 | 作为 Bootstrap 组件 |
| Iconfont | 阿里巴巴矢量图标库 | 用户可以自定义下载多种格式的 icon,也可将图标转换为字体,便于前端工程师自由调整与调用 |
| UI 框架 | ||
| WeUI | 同微信原生视觉体验一致的基础样式库 | Demo、Wiki |
| Apple UI Design Resources | 苹果用户界面设计资源 | |
程序设计规范:
【推荐】上传的文件直接保存到文件存储服务(如阿里云 OSS),这样即使被上传了后门 shell,对网站服务器也不会有影响。
否则必须通过文件头来确定文件类型,检查文件十六进制的文件头和文件尾是否合法,并检查文件流中是否包含 php、evel 等字符。
不可直接使用客户端文件名来保存文件,特别是后缀名/扩展名。应生成随机文件名,并通过检验文件头来确定文件类型。必须由程序指定保存目录。
使用 OSS 的应直接上传,不要在 ECS 上临时存放或备份。如必须存放的,应按上述规范操作。
服务器安全设置
CentOS + nginx + PHP:
全站文件取消属性中的“执行”权限(chmod),因为这个“执行”与运行 PHP 无关。而需要上传文件的“目录”需要“执行”权限,原因是需要往该目录创建文件。
仅需要写入的目录或文件设置“写入”权限。如上传图片目录、ThinkPHP 的 Runtime 目录。
凡可写目录或文件均不允许运行 PHP / PY 等 除需要被直接访问的 PHP / PY 文件,其它动态文件均不允许被访问到,在 nginx 的配置文件中添加项,参:https://xoyozo.net/Blog/Details/nginx-location-if,若全站使用统一的入口文件访问,那么设置仅该文件允许运行 PHP 即可。通过 IO 方式被其它文件包含的文件,无需运行 PHP 权限。(“deny all”对 include 起作用,但对 IO 不起作用,因此 Runtime 目录可以继续为 ThinkPHP 提供缓存服务。)这一步非常有用。
使用与 nginx 网站用户不同的用户来部署网站文件,如宝塔面板 PHP 使用 www 用户,那么就使用 root 或其它新用户来上传文件,否则将导致全站目录和文件可写。有条件的建议不同网站使用不同的用户,可防止一个网站被入侵后导致其它网站文件或磁盘上的其它文件被泄露的风险(2022年10月2日从宝塔官方社区获悉,宝塔面板暂不支持使用非 www 用户创建并运行网站)。
Windows Server + IIS + ASP.NET:
配置每个磁盘的安全属性,拒绝“IIS_IUSRS”这个用户组的所有权限。只要设置驱动器即可,子文件夹和文件会自动继承。若运行 .NET Framework 项目,需要设置 C:\Windows\Microsoft.NET\Framework\v*.*.*****\Temporary ASP.NET Files\ 目录可修改写入权限,.NET Core 项目不需要此设置。
为每个网站创建一个新用户,仅隶属于“IIS_IUSRS”。网站根目录安全属性添加该用户,权限选择“读取”。(已测取消“读取与执行”不影响 PHP,“列出文件夹内容”视业务需求开启,建议关闭)。仅需要上传文件的目录或文件设置“修改”、“写入”权限。(修改对应修改文件,写入对应上传文件)
IIS 网站中设置“物理路径凭据”以及应用程序池的“标识”。
IIS 中设置写入目录的“处理程序映射”无脚本。
《Windows Server 2008 R2 Web 服务搭建流程》
前提一、安装完系统后,各分区的权限均设为:
IIS_IUSRS 完全拒绝(不是什么都不勾,而是勾满右侧的拒绝)
一、创建网站用户,如 netXoyozoWww,密码永不过期,仅隶属于 IIS_IUSRS 组。
二、创建网站根目录 net.xoyozo.www,权限添加用户 netXoyozoWww, 允许“读取和执行”、“列出文件夹内容”、“读取”。
创建上传目录 upload,用户 netXoyozoWww 的权限再允许“修改”、“写入”。
三、IIS 中添加网站,网站名称如 net.xoyozo.www,指定物理路径,点击连接为,特定用户,测试设置……
主机名 www.xoyozo.net
四、应用程序池,把 net.xoyozo.www 改成实际需要的 .NET 版本;高级设置,标识,自定义帐户 netXoyozoWww
五、选中网站,日志,更改目录,应用
六、展示网站目录树,选中 upload,处理程序映射,编辑功能权限,取消“脚本”前的勾。
此操作的结果会在该目录下创建 web.config 文件,切勿删除!尚未研究出被上传文件替换的解决方案。程序应严格控制上传路径,阻止修改或替换 web.config 文件
另:
查看端口命令:netstat -an
http://npoi.codeplex.com/documentation
免费,开源,无需安装 Office,功能强大,兼容性好,使用方便,可以在 Visual Studio 的 NuGet 管理器中直接搜索安装。
导出 Excel 简单示例:
HSSFWorkbook book = new HSSFWorkbook();
ISheet sheet = book.CreateSheet("工作表1");
IRow r0 = sheet.CreateRow(0);
r0.CreateCell(0).SetCellValue("行1列1");
r0.CreateCell(1).SetCellValue("行1列2");
IRow r1 = sheet.CreateRow(1);
r1.CreateCell(0).SetCellValue("行2列1");
r1.CreateCell(2).SetCellValue("行2列3");
MemoryStream ms = new MemoryStream();
book.Write(ms);
Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.xls", "文件名"));
Response.BinaryWrite(ms.ToArray());
Response.End();
book = null;
ms.Close();
ms.Dispose();字体相关:
ICellStyle style = book.CreateCellStyle();
IFont font = book.CreateFont();
font.FontHeightInPoints = 20; // 字体大小
font.Color = HSSFColor.White.Index; // 字体颜色
style.SetFont(font);
style.FillForegroundColor = HSSFColor.Red.Index; // 背景色
style.FillPattern = FillPattern.SolidForeground;
cell.CellStyle = style;合并单元格:
CellRangeAddress cra = new CellRangeAddress(r - 1, r - 1, c - 1, c);
sheet.AddMergedRegion(cra);宽度自适应:
for (int i = 1; i < c; i++) {
sheet.AutoSizeColumn(i);
}函数:
cell.SetCellFormula("SUM(B2:B4)");顺便提一句,ICellStyle 和 IFont 最好一种样式一个变量先定义好再用,不要在循环里疯狂地 Create,否则超出数量(512个)会导致样式失效。
其它参考:http://www.ez2o.com/Blog/Post/csharp-Excel-NPOI-Font-Style
数据库设计规范是个技术含量相对低的话题,只需要对标准和规范的坚持即可做到。当系统越来越庞大,严格控制数据库的设计人员,并且有一份规范书供执行参考。在程序框架中,也有一份强制性的约定,当不遵守规范时报错误。
以下20个条款是我从一个超过1000个数据库表的大型ERP系统中提炼出来的设计约定,供参考。
1 所有的表的第一个字段是记录编号Recnum,用于数据维护
[Recnum] [decimal] (8, 0) NOT NULL IDENTITY(1, 1)
在进行数据维护的时候,我们可以直接这样写:
UPDATE Company SET Code='FLEX' WHERE Recnum=23
2 每个表增加4个必备字段,用于记录该笔数据的创建时间,创建人,最后修改人,最后修改时间
[CreatedDate] [datetime] NULL, [CreatedBy] [nvarchar] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, [RevisedDate] [datetime] NULL, [RevisedBy] [nvarchar] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
框架程序中会强制读取这几个字段,默认写入值。
3 主从表的主外键设计
主表用参考编号RefNo作为主键,从表用RefNo,EntryNo作为主键。RefNo是字符串类型,可用于单据编码功能中自动填写单据流水号,从表的EntryNo是行号,LineNo是SQL Server 的关键字,所以用EntryNo作为行号。
如果是三层表,则第三层表的主键依次是RefNo,EntryNo,DetailEntryNo,第三个主键用于自动增长行号。
4 设计单据状态字段
| 字段 | 含义 |
| Posted | 过帐,已确认 |
| Closed | 已完成 |
| Cancelled | 已取消 |
| Approved | 已批核 |
| Issued | 已发料 |
| Finished | 已完成 |
| Suspended | 已取消 |
5 字段含义相近,把相同的单词调成前缀。
比如工作单中的成本核算,人工成本,机器成本,能源成本,用英文表示为LaborCost,MachineCost,EnergyCost
但是为了方便规组,我们把Cost调到字段的前面,于是上面三个字段命名为CostLabor,CostMachine,CostEnergy。
可读性后者要比前者好一点,Visual Studio或SQL Prompt智能感知也可帮助提高字段输入的准确率。
6 单据引用键命名 SourceRefNo SourceEntryNo
销售送货Shipment会引用到是送哪张销售单据的,可以添加如下引用键SourceRefNo,SourceEntryNo,表示送货单引用的销售单的参考编号和行号。Source开头的字段一般用于单据引用关联。
7 数据字典键设计
比如员工主档界面的员工性别Gender,我的方法是在源代码中用枚举定义。性别枚举定义如下:
public enum Gender
{
[StringValue("M")]
[DisplayText("Male")]
Male,
[StringValue("F")]
[DisplayText("Female")]
Female
}
在代码中调用枚举的通用方法,读取枚举的StringValue写入到数据库中,读取枚举的DisplayText显示在界面中。
经过这一层设计,数据库中有关字典方面的设计就规范起来了,避免了数据字典的项的增减给系统带来的问题。
8 数值类型字段长度设计
Price/Qty 数量/单价 6个小数位 nnnnnnnnnn.nnnnnn 格式 (10.6)
Amount 金额 2个小数位 nnnnnnnnnnnn.nn 格式(12.2)
Total Amt 总金额 2个小数位 nnnnnnnnnnnnnn.nn 格式(14.2)
参考编号默认16个字符长度,不够用的情况下增加到30个字符,再不够用增加到60个字符。这样可以保证每张单据的第一个参考编号输入控件看起来都是一样长度。
除非特别需求,一般而言,界面中控件的长度取自映射的数据库中字段的定义长度。
9 每个单据表头和明细各增加10个自定义字段,基础资料表增加20个自定义字段
参考供应商主档的自定义字段,自定义字段的名称统一用UserDefinedField。
ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_1] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_2] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_3] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_4] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_5] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_6] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_7] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_8] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_9] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_10] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_11] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_12] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_13] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_14] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_15] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_16] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_17] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_18] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_19] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ALTER TABLE Vendor ADD COLUMN [USER_DEFINED_FIELD_20] nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
10 多货币(本位币)转换字段的设计
金额或单价默认是以日记帐中的货币为记录,当默认货币与本位币不同时需要同时记录下本位币的值。
销售单销售金额 SalesAmount或SalesAmt,本位币字段定义为SalesAmountLocal或SalesAmtLocal
通常是在原来的字段后面加Local表示本位币的值。
11 各种日期字段的设计
| 字段名称 | 含义 |
| TranDate | 日期帐日期 Tran是Transaction的简写 |
| PostedDate | 过帐日期 |
| ClosedDate | 完成日期 |
| InvoiceDate | 开发票日期 |
| DueDate | 截止日期 |
| ScheduleDate | 计划日期,这个字段用在不同的单据含义不同。比如销售单是指送货日期,采购单是指收货日期。 |
| OrderDate | 订单日期 |
| PayDate | 付款日期 |
| CreatedDate | 创建日期 |
| RevisedDate | 修改日期 |
| SettleDate | 付款日期 |
| IssueDate | 发出日期 |
| ReceiptDate | 收货日期 |
| ExpireDate | 过期时间 |
12 财务有关的单据包含三个标准字段
FiscalYear 财年,PeriodNo 会计期间,Period 前面二个的组合。以国外的财年为例子,FiscalYear是2015,PeriodNo是4,Period是2015/04。
欧美会计期间是从每年的4月份开始,需要注意的是会计期间与时间没有必然的联系,看到会计期间是2015/04,不一定是表示2015的4月份,它只是说这是2015财年的第四期,具体在哪个时间段需要看会计期间定义。
13 单据自动生成 DirectEntry
有些单据是由其它单据生成过来的,逻辑上应该不支持编辑。比如销售送货Shipment单会产生出仓单,出仓单应该不支持编辑,只能做过帐扣减库存操作。这时需要DirectEntry标准字段来表示。当手工创建一张出仓单时,将DirectEntry设为true,表示可编辑单据中的字段值,当由其它单据传递产生过来产生的出仓单,将DirectEntry设为false,表示不能编辑此单据。这种情况还发生在业务单据产生记帐凭证(Voucher)的功能中,如果可以修改由原始单据传递过来的数量金额等字段,则会导致与源单不匹配,给系统对帐产生困扰。
14 百分比值字段的设计
Percentage百分比值,用于折扣率,损耗率等相关比率设定的地方。推荐用数值类型表示,用脚本表示是
[ScrapRate] [decimal] (5, 2) NULL
预留两位小数,整数部分支持1-999三位数。常常是整数部分2位就可以,用3位也是为了支持一些特殊行业(物料损耗率超过100)的要求。
15 日志表记录编号LogNo字段设计
LogNo字段的设计有些巧妙,以出仓单为例子,一张出仓单有5行物料明细,每一行物料出仓都会扣减库存,再写物料进出日记帐,因为这五行物料出仓来自同一个出仓单,于是将这五行物料的日记帐中的LogNo都设为同一个值。于在查询数据时,以这个字段分组即可看到哪些物料是在同一个时间点上出仓的,对快速查询有很重要的作用。
16 基础资料表增加名称,名称长写,代用名称三个字段
比如供应商Vendor表,给它加以下三个字段:
Description 供应商名称,比如微软公司。
ExtDescription 供应商名称长写,比如电气行业的南网的全名是南方国家电网有限公司。
AltDescription 供应商名称替代名称,用在报表或是其它单据引用中。比如采购单中的供应商是用微软,还是用代用名称Microsoft,由参数(是否用代用名称)控制。
17 文件类表增加MD5 Hash字段
比如产品数据管理系统要读取图纸,单据功能中增加的附件文件,这类涉及文件读写引用的地方,考虑存放文件的MD5哈希值。文件的MD5相当于文件的唯一识别身份,在网上下载文件时,网站常常会放出文件的MD5值,以方便对比核对。当下载到本机的文件的MD5值与网站上给出的值不一致时,有可能这个文件被第三方程序修改过,不可信任。
18 数据表的主键用字符串而不是数字
比如销售单中的货币字段,是存放货币表的货币字符串值RMB/HKD/USD,还是存放货币表的数字键,1/2/3。
存放前者对于报表制作相对容易,但是修改起来相对麻烦。存放后者对修改数据容易,但对报表类或查询类操作都需要增加一个左右连接来看数字代表的货币。金蝶使用的是后者,它的BOS系统也不允许数据表之间有直接的关联,而是间接通过Id值来关联表。
在我看到的系统中,只有一个会计期间功能(财年Fiscal Year)用到数字值作主键,其余的单据全部是字符串做主键。
19 使用约定俗成的简写
模块Module 简写
| 简写 | 全名 |
| SL | Sales 销售 |
| PU | Purchasing 采购 |
| IC | Inventory 仓库 |
| AR | Account Receivable 应收 |
| AP | Account Payable 应付 |
| GL | General Ledger 总帐 |
| PR | Production 生产 |
名称Name 简写
| 简写 | 全名 |
| Uom | Unit of Measure 单位 |
| Ccy | Currency 货币 |
| Amt | Amount 金额 |
| Qty | Quantity 数量 |
| Qty Per | Quantity Per 用量 |
| Std Output | Standard Output 标准产量 |
| ETA | Estimated Time of Arrival 预定到达时间 |
| ETD | Estimated Time of Departure 预定出发时间 |
| COD | Cash On Delivery 货到付款 |
| SO | Sales Order 销售单 |
| PO | Purchase Order 采购单 |
20 库存单据数量状态
Qty On Hand 在手量
Qty Available 可用量
Qty On Inspect 在验数量
Qty On Commited 提交数量
Qty Reserved 预留数量
以上每个字段都有标准和行业约定的含义,不可随意修改取数方法。
PHP如何获取表单的POST数据呢?本文介绍3种获取POST数据的方法,并将代码附上,希望可以帮助到你。
一、PHP获取POST数据的几种方法
方法1、最常见的方法是:$_POST['fieldname'];
说明:只能接收Content-Type: application/x-www-form-urlencoded提交的数据
解释:也就是表单POST过来的数据
方法2、file_get_contents(“php://input”);
说明:
允许读取 POST 的原始数据。
和 $HTTP_RAW_POST_DATA 比起来,它给内存带来的压力较小,并且不需要任何特殊的 php.ini 设置。
php://input 不能用于 enctype=”multipart/form-data”。
解释:
对于未指定 Content-Type 的POST数据,则可以使用file_get_contents(“php://input”);来获取原始数据。
事实上,用PHP接收POST的任何数据都可以使用本方法。而不用考虑Content-Type,包括二进制文件流也可以。
所以用方法二是最保险的方法。
方法3、$GLOBALS['HTTP_RAW_POST_DATA'];
说明:
总是产生 $HTTP_RAW_POST_DATA 变量包含有原始的 POST 数据。
此变量仅在碰到未识别 MIME 类型的数据时产生。
$HTTP_RAW_POST_DATA 对于 enctype=”multipart/form-data” 表单数据不可用
如果post过来的数据不是PHP能够识别的,可以用 $GLOBALS['HTTP_RAW_POST_DATA']来接收,
比如 text/xml 或者 soap 等等
解释:
$GLOBALS['HTTP_RAW_POST_DATA']存放的是POST过来的原始数据。
$_POST或$_REQUEST存放的是 PHP以key=>value的形式格式化以后的数据。
但$GLOBALS['HTTP_RAW_POST_DATA']中是否保存POST过来的数据取决于centent-Type的设置,即POST数据时 必须显式示指明Content-Type: application/x-www-form-urlencoded,POST的数据才会存放到 $GLOBALS['HTTP_RAW_POST_DATA']中。
二、演示
1、PHP 如何获取POST过来的XML数据和解析XML数据
比如我们在开发微信企业号时,如何处理用户回复过来的数据呢?
文档:http://qydev.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E6%94%B6%E6%99%AE%E9%80%9A%E6%B6%88%E6%81%AF
首先查阅文档,可知道:启用开发模式后,当用户给应用回复信息时,微信服务端会POST一串XML数据到已验证的回调URL
假设该URL为 http://www.xxx.com
Http请求方式: POST
http://www.xxx.com/?msg_signature=ASDFQWEXZCVAQFASDFASDFSS×tamp=13500001234&nonce=123412323
POST的XML内容为:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[this is a test]]></Content> <MsgId>1234567890123456</MsgId> <AgentID>1</AgentID> </xml>
那么怎么接收这段内容呃?
这时就可以用到:方法2(file_get_contents(“php://input”))、方法3($GLOBALS['HTTP_RAW_POST_DATA'])
方法2(file_get_contents(“php://input”)):
$input = file_get_contents("php://input"); //接收POST数据
$xml = simplexml_load_string($input); //提取POST数据为simplexml对象
var_dump($xml);
方法3($GLOBALS['HTTP_RAW_POST_DATA'])
$input = $GLOBALS['HTTP_RAW_POST_DATA']; libxml_disable_entity_loader(true); $xml = simplexml_load_string($input, 'SimpleXMLElement', LIBXML_NOCDATA); var_dump($xml);
PHP获取POST数据的3种方法及其代码分析,希望可以帮到你。
有时候已知一个 ID 的数组,需要读取这些记录内容,SQL 可以联接多个“或”关系去读取,或使用“In”语句,在 LINQ TO SQL 中可以这样来做:
List<int> ids = new List<int> { 1, 2, 3 };
List<string> tbs = db.dbTables.Where(c => ids.Contains<int>(c.ID)).ToList();