程序员@老李 - PHP 2023-11-09T13:18:21+08:00 Typecho https://blog.mostion.com/feed/atom/category/php/ <![CDATA[CentOS yum 安装lnmp相关配置]]> https://blog.mostion.com/archives/36/ 2023-11-09T13:18:21+08:00 2023-11-09T13:18:21+08:00 Jason http://blog.mostion.com 查看系统版本
cat /etc/os-release
cat /etc/redhat-release
rpm -q centos-release

查看内核

uname -a

安装epel

yum -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-zip
yum -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-zip
yum -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-phalcon4
yum -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包

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.log

MySQL 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 Headers

  • redhat系列

    sudo yum -y install kernel-headers  //安装kernel-headers
    sudo yum -y install kernel-devel    //安装kernel-devel
  • debian系列

    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;
}
]]>
<![CDATA[Laravel实现适用于API的分页查询]]> https://blog.mostion.com/archives/34/ 2023-11-06T08:36:00+08:00 2023-11-06T08:36:00+08:00 Jason http://blog.mostion.com 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;

]]>
<![CDATA[php-fpm 调优和配置]]> https://blog.mostion.com/archives/33/ 2023-11-05T09:08:20+08:00 2023-11-05T09:08:20+08:00 Jason http://blog.mostion.com 知识点
  • 一般 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 . 默认值: 空.
]]>