程序员@老李 - PHP
https://blog.mostion.com/category/php/
-
CentOS yum 安装lnmp相关配置
https://blog.mostion.com/archives/36/
2023-11-09T13:18:21+08:00
查看系统版本cat /etc/os-release
cat /etc/redhat-release
rpm -q centos-release查看内核uname -a安装epelyum -y install epel-release
rpm -ivh http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7安装remi#remi源需要手动启用
rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi
yum install -y yum-utils
yum-config-manager --enable remi > /dev/null安装php71#!/bin/bash
yum -y install \
openssl \
openssl-devel \
libmcrypt \
libmcrypt-devel \
php71 \
php71-php \
php71-php-gd \
php71-php-mysqlnd \
php71-php-mcrypt \
php71-php-imap \
php71-php-ldap \
php71-php-mbstring \
php71-php-pear \
php71-php-xml \
php71-php-xmlrpc \
php71-php-soap \
php71-php-bcmath \
php71-php-mcrypt \
php71-php-fpm \
php71-php-pecl-http \
php71-php-pecl-redis \
php71-php-opcache \
php71-php-pecl-zip //phpexcel 必须#!/bin/bash
yum -y install \
openssl \
openssl-devel \
libmcrypt \
libmcrypt-devel \
php74 \
php74-php \
php74-php-gd \
php74-php-mysqlnd \
php74-php-mcrypt \
php74-php-imap \
php74-php-ldap \
php74-php-mbstring \
php74-php-pear \
php74-php-xml \
php74-php-xmlrpc \
php74-php-soap \
php74-php-bcmath \
php74-php-mcrypt \
php74-php-fpm \
php74-php-pecl-http \
php74-php-pecl-redis \
php74-php-opcache \
php74-php-pecl-zip //phpexcel 必须
yum -y install openssl openssl-devel libmcrypt libmcrypt-devel php71 php71-php php71-php-gd php71-php-mysqlnd php71-php-mcrypt php71-php-imap php71-php-ldap php71-php-mbstring php71-php-pear php71-php-xml php71-php-xmlrpc php71-php-soap php71-php-bcmath php71-php-mcrypt php71-php-fpm php71-php-pecl-http php71-php-pecl-redis php71-php-opcache php71-php-pecl-zipyum -y install openssl openssl-devel libmcrypt libmcrypt-devel php72 php72-php php72-php-gd php72-php-mysqlnd php72-php-mcrypt php72-php-imap php72-php-ldap php72-php-mbstring php72-php-pear php72-php-xml php72-php-xmlrpc php72-php-soap php72-php-bcmath php72-php-mcrypt php72-php-fpm php72-php-pecl-http php72-php-pecl-redis php72-php-opcache php72-php-pecl-zipyum -y install openssl openssl-devel libmcrypt libmcrypt-devel php73 php73-php php73-php-gd php73-php-mysqlnd php73-php-mcrypt php73-php-imap php73-php-ldap php73-php-mbstring php73-php-pear php73-php-xml php73-php-xmlrpc php73-php-soap php73-php-bcmath php73-php-mcrypt php73-php-fpm php73-php-pecl-http php73-php-pecl-redis php73-php-opcache php73-php-pecl-zip php73-php-pecl-redis4 php73-php-phalcon4yum -y install openssl openssl-devel libmcrypt libmcrypt-devel php80 php80-php php80-php-gd php80-php-mysqlnd php80-php-mcrypt php80-php-imap php80-php-ldap php80-php-mbstring php80-php-pear php80-php-xml php80-php-xmlrpc php80-php-soap php80-php-bcmath php80-php-mcrypt php80-php-fpm php80-php-pecl-http php80-php-opcache php80-php-pecl-zip php80-php-pecl-redis5 php80-php-phalcon4#修改yum设置,让rpm包缓存到本地
vi /etc/yum.conf
#修改keepcache为1
keepcache=1
#清空yum缓存
yum clean all
#安装你要离线安装的rpm包
yum install xxx.rpm -y
#rpm包缓存到了/var/cache/yum下面
cd /var/cache/yum
find ./ -name *.rpm
#找到你的rpm包,并拷走就可以离线安装了安装php56#!/bin/bash
yum -y install \
libmcrypt \
libmcrypt-devel \
# libjpeg* \
php56 \
php56-php \
php56-php-gd \
php56-php-mysqlnd \
php56-php-mcrypt \
php56-php-imap \
php56-php-ldap \
php56-php-mbstring \
php56-php-pear \
php56-php-xml \
php56-php-xmlrpc \
php56-php-soap \
php56-php-bcmath \
php56-php-mcrypt \
php56-php-fpm \
php56-php-pecl-http \
php56-php-pecl-redis \
php56-php-opcache# 查看某个包的信息
yum --enablerepo=epel info htop
# 列出epel信息
yum --disablerepo="*" --enablerepo="epel" list available | less安装MySQL访问地址 下载对应的rpm包http://dev.mysql.com/downloads/repo/yum/安装源wget https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
yum localinstall mysql80-community-release-el7-1.noarch.rpm手动启用想要的版本yum -y install mysql-community-server
yum -y install mysql-community-client启动服务# 启动服务
systemctl start mysqld
# 初始化
mysql_secure_installation初始密码cat /var/log/mysqld.logMySQL 2059错误alter user root@localhost identified by 'password' password expire never;
alter user root@localhost identified with mysql_native_password by 'password';
flush privileges;安装开发工具包yum groupinstall "Development Tools" "Development Libraries"
yum install gcc gcc-c++ gcc-g77 flex bison \
autoconf automake bzip2-devel zlib-devel \
ncurses-devel libjpeg-devel libpng-devel \
libtiff-devel freetype-devel pam-devel \
openssl-devel libxml2-devel gettext-devel \
pcre-devel系统服务目录/usr/lib/systemd/system/ #RPM包安装时分发的unit文件
/run/systemd/system/ #systemd运行时创建的文件
/etc/systemd/system/ #systemctl enable创建的unit文件Linux Headersredhat系列sudo yum -y install kernel-headers //安装kernel-headers
sudo yum -y install kernel-devel //安装kernel-develdebian系列sudo apt-get install build-essential //install build-essential(optional)
sudo apt-get update //install linux-headers
sudo apt-get install linux-headers-$(uname -r)
sudo apt-get update && sudo apt-get install build-essential linux-headers-$(uname -r)#discuz 安全
location ~ /(template|attachment|upload)/.*\.(php|php5|PHP|PHP5)?$ {
deny all;
}
-
Laravel实现适用于API的分页查询
https://blog.mostion.com/archives/34/
2023-11-06T08:36:00+08:00
Laravel 实现适用于 API 的分页查询Laravel自带分页查询方法里有一些多余的数据,并不完美适用于我们用来做API的查询。本文旨在通过重写 paginate 解决分页查询针对API接口的的灵活性和适用性。新建BaseModel.php文件,代码如下:<?php
namespace App\Http\Model;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Pagination\Paginator;
class BaseModel extends Model{
public $timestamps = false;
//重写分页方法,使其更加匹配API的规范
//考虑到性能问题,通常$columns我们不以*号为值。可传入需要查询的字段替代。这里只做演示。无此要求
public function paginate($perPage = null, $columns = ['*'], $page = null, $pageName = 'page'){
$page = $page ?: Paginator::resolveCurrentPage($pageName);
$perPage = $perPage ?: $this->model->getPerPage();
$results = ($total = $this->toBase()->getCountForPagination())
? $this->forPage($page, $perPage)->get($columns)
: $this->model->newCollection();
$pages = ceil($total / $perPage);
$result = ['total'=>$total,'current_page'=>$page,'page_size'=>$perPage,'pages'=>$pages,'list'=>$results];
return $result;
}
}
然后在业务模型继承此类即可,范例如下:<?php
namespace App\Http\Model;
class MsgBoard extends BaseModel{
protected $table = 'msg_board';
public function getMsgPageList($page,$pageSize){
return $this->paginate($pageSize, ['*'], $page, 'page');
}
}
然后在控制器当中调用即可。范例如下:$page = $request->input('page',1);
$pageSize = $request->input('pageSize',12);
$msgList = $mMsgBoard->getMsgPageList($page,$pageSize);THE END;
-
php-fpm 调优和配置
https://blog.mostion.com/archives/33/
2023-11-05T09:08:20+08:00
知识点一般 php-fpm 进程占用20~30m左右的内存就按30m算。如果单独跑php-fpm,动态方式起始值可设置物理内存Mem/30M,由于大家一般Nginx、MySQL都在一台机器上,于是预留一半给它们,即php-fpm进程数(max_children)为$Mem/2/30。max_requests:指一个php-fpm的工作进程在处理多少个请求后就终止掉。这个用来处理因为PHP解析器或引用的第三方库时,造成的内存泄露问题。一般原则是:动态适合小内存机器,灵活分配进程,省内存。静态适用于大内存机器,动态创建回收进程对服务器资源也是一种消耗常用命令查看当前php-fpm总进程数,命令:ps -ylC php-fpm --sort:rss 。其中RSS就是占用的内存情况查看当前php-fpm进程的内存占用情况及启动时间,命令如下:ps -e -o 'pid,comm,args,pcpu,rsz,vsz,stime,user,uid'|grep www|sort -nrk5查看当前php-fpm进程平均占用内存情况:ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'配置详解:pid = /usr/local/var/run/php-fpm.pid
#pid设置,一定要开启,上面是Mac平台的。默认在php安装目录中的var/run/php-fpm.pid。比如centos的在: /usr/local/php/var/run/php-fpm.pid
error_log = /usr/local/var/log/php-fpm.log
#错误日志,上面是Mac平台的,默认在php安装目录中的var/log/php-fpm.log,比如centos的在: /usr/local/php/var/log/php-fpm.log
log_level = notice
#错误级别. 上面的php-fpm.log纪录的登记。可用级别为: alert(必须立即处理), error(错误情况), warning(警告情况), notice(一般重要信息), debug(调试信息). 默认: notice.
emergency_restart_threshold = 60
emergency_restart_interval = 60s
#表示在emergency_restart_interval所设值内出现SIGSEGV或者SIGBUS错误的php-cgi进程数如果超过 emergency_restart_threshold个,php-fpm就会优雅重启。这两个选项一般保持默认值。0 表示 '关闭该功能'. 默认值: 0 (关闭).
process_control_timeout = 0
#设置子进程接受主进程复用信号的超时时间. 可用单位: s(秒), m(分), h(小时), 或者 d(天) 默认单位: s(秒). 默认值: 0.
daemonize = yes
#后台执行fpm,默认值为yes,如果为了调试可以改为no。在FPM中,可以使用不同的设置来运行多个进程池。 这些设置可以针对每个进程池单独设置。
listen = 127.0.0.1:9000
#fpm监听端口,即nginx中php处理的地址,一般默认值即可。可用格式为: 'ip:port', 'port', '/path/to/unix/socket'. 每个进程池都需要设置。如果nginx和php在不同的机器上,分布式处理,就设置ip这里就可以了。
listen.backlog = -1
#backlog数,设置 listen 的半连接队列长度,-1表示无限制,由操作系统决定,此行注释掉就行。backlog含义参考:http://www.3gyou.cc/?p=41
listen.allowed_clients = 127.0.0.1
#允许访问FastCGI进程的IP白名单,设置any为不限制IP,如果要设置其他主机的nginx也能访问这台FPM进程,listen处要设置成本地可被访问的IP。默认值是any。每个地址是用逗号分隔. 如果没有设置或者为空,则允许任何服务器请求连接。
listen.owner = www
listen.group = www
listen.mode = 0666
#unix socket设置选项,如果使用tcp方式访问,这里注释即可。
user = www
group = www
#启动进程的用户和用户组,FPM 进程运行的Unix用户, 必须要设置。用户组,如果没有设置,则默认用户的组被使用。
pm = dynamic
#php-fpm进程启动模式,pm可以设置为static和dynamic和ondemand
#如果选择static,则进程数就数固定的,由pm.max_children指定固定的子进程数。
#如果选择dynamic,则进程数是动态变化的,由以下参数决定:
pm.max_children = 50 #子进程最大数
pm.start_servers = 2 #启动时的进程数,默认值为: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
pm.min_spare_servers = 1 #保证空闲进程数最小值,如果空闲进程小于此值,则创建新的子进程
pm.max_spare_servers = 3 #,保证空闲进程数最大值,如果空闲进程大于此值,此进行清理
pm.max_requests = 500
#设置每个子进程重生之前服务的请求数. 对于可能存在内存泄漏的第三方模块来说是非常有用的. 如果设置为 '0' 则一直接受请求. 等同于 PHP_FCGI_MAX_REQUESTS 环境变量. 默认值: 0.
pm.status_path = /status
#FPM状态页面的网址. 如果没有设置, 则无法访问状态页面. 默认值: none. munin监控会使用到
ping.path = /ping
#FPM监控页面的ping网址. 如果没有设置, 则无法访问ping页面. 该页面用于外部检测FPM是否存活并且可以响应请求. 请注意必须以斜线开头 (/)。
ping.response = pong
#用于定义ping请求的返回相应. 返回为 HTTP 200 的 text/plain 格式文本. 默认值: pong.
access.log = log/$pool.access.log
#每一个请求的访问日志,默认是关闭的。
access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
#设定访问日志的格式。
slowlog = log/$pool.log.slow
#慢请求的记录日志,配合request_slowlog_timeout使用,默认关闭
request_slowlog_timeout = 10s
#当一个请求该设置的超时时间后,就会将对应的PHP调用堆栈信息完整写入到慢日志中. 设置为 '0' 表示 'Off'
request_terminate_timeout = 0
#设置单个请求的超时中止时间. 该选项可能会对php.ini设置中的'max_execution_time'因为某些特殊原因没有中止运行的脚本有用. 设置为 '0' 表示 'Off'.当经常出现502错误时可以尝试更改此选项。
rlimit_files = 1024
#设置文件打开描述符的rlimit限制. 默认值: 系统定义值默认可打开句柄是1024,可使用 ulimit -n查看,ulimit -n 2048修改。
rlimit_core = 0
#设置核心rlimit最大限制值. 可用值: 'unlimited' 、0或者正整数. 默认值: 系统定义值.
chroot =
#启动时的Chroot目录. 所定义的目录需要是绝对路径. 如果没有设置, 则chroot不被使用.
chdir =
#设置启动目录,启动时会自动Chdir到该目录. 所定义的目录需要是绝对路径. 默认值: 当前目录,或者/目录(chroot时)
catch_workers_output = yes
#重定向运行过程中的stdout和stderr到主要的错误日志文件中. 如果没有设置, stdout 和 stderr 将会根据FastCGI的规则被重定向到 /dev/null . 默认值: 空.