PHP开启错误显示,php.ini配置修改 PHP

前言

PHP报错了,页面白屏或者500,啥也不显示,不知道哪错了?开了错误显示就能看到具体错误了。本文讲怎么改php.ini开启错误显示。

一、为什么不显示错误

生产环境为了安全,默认不显示错误,防止暴露敏感信息(路径、数据库密码等)。

但开发的时候就不方便了,啥也看不到。

二、找到php.ini

找php.ini位置

php --ini

输出:

Loaded Configuration File: /etc/php.ini

或者:

/etc/php/7.4/cli/php.ini

注意:CLI和FPM的php.ini可能不一样。

看当前加载的是哪个

写个phpinfo:

<?php
phpinfo();
?>

浏览器访问,看Loaded Configuration File。

三、修改php.ini

1. 显示错误

display_errors = On

2. 报错级别

error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

或者全开:

error_reporting = E_ALL

3. 错误日志

log_errors = On
error_log = /var/log/php_errors.log

4. 显示启动错误

display_startup_errors = On

四、改完重启

PHP-FPM

systemctl restart php-fpm

或者:

systemctl reload php-fpm

Apache

systemctl restart httpd

五、代码里临时开启

不想改php.ini,在代码开头加:

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

或者:

ini_set('error_reporting', E_ALL);
ini_set('display_errors', 1);

六、常见错误类型

E_ALL

所有错误和警告。

E_ERROR

致命运行错误,脚本停止。

E_WARNING

运行时警告,脚本继续。

E_NOTICE

运行时注意,比如未定义变量。

七、常见坑

坑1:改了php.ini不生效

改的不是实际加载的那个php.ini。

解决: 用 php --ini 看实际加载的是哪个。

坑2:FPM和CLI的php.ini不一样

命令行改了,网页上不生效。

原因: CLI和FPM用不同的php.ini。

解决: 改FPM的那个,比如 /etc/php/7.4/fpm/php.ini。

坑3:页面白屏

可能是语法错误,php.ini都没加载起来。

检查: 看PHP错误日志。

坑4:开了错误显示有安全风险

生产环境不能开!

注意: 排查完一定要改回去。

坑5:.htaccess里覆盖了

有些主机在.htaccess里设了php_flag。

检查: 看看.htaccess里有没有。

八、生产环境配置

生产环境不要开display_errors,但要开日志:

display_errors = Off
log_errors = On
error_log = /var/log/php_errors.log
error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED

九、查看错误日志

PHP错误日志

tail -f /var/log/php_errors.log

Nginx错误日志

tail -f /var/log/nginx/error.log

Apache错误日志

tail -f /var/log/httpd/error_log

十、快速排查

第一步:代码里临时开

ini_set('display_errors', 1);
error_reporting(E_ALL);

第二步:看具体报错

刷新页面,看报什么错。

第三步:解决完删掉

改完了把代码里的ini_set删掉,或者改回生产配置。

总结

记住:

  1. display_errors = On 显示错误
  2. error_reporting = E_ALL 显示所有错误
  3. 改完重启php-fpm
  4. 生产环境关掉display_errors,开log_errors
  5. 代码里可以用ini_set临时开

开发环境推荐:

display_errors = On
error_reporting = E_ALL
log_errors = On

生产环境推荐:

display_errors = Off
log_errors = On
error_reporting = E_ALL & ~E_NOTICE

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 08:34 

ThinkPHP6 500报错,开启错误日志查看原因 PHP

前言

ThinkPHP6网站突然500报错,页面啥也不显示,不知道哪错了?本文讲怎么开启错误显示和日志,快速定位问题。

一、为什么500不显示错误

生产环境为了安全,关闭了错误显示,直接返回500,不显示具体错误信息。

这是对的,不然用户能看到你的代码路径、数据库密码等敏感信息。

但排查问题就不方便了。

二、临时开启错误显示

修改 .env 文件

项目根目录下有个 .env 文件:

APP_DEBUG = true

把 APP_DEBUG 改成 true。

刷新页面,就能看到具体错误了。

注意

排查完记得改回 false! 生产环境不能开debug。

三、开启日志记录

就算不开debug,错误也会记录到日志文件里。

日志配置

config/log.php 文件:

return [
    // 默认日志通道
    'default' => 'file',

    // 日志通道列表
    'channels' => [
        'file' => [
            // 日志记录方式
            'type' => 'File',
            // 日志保存目录
            'path' => '',
            // 单文件日志写入
            'single' => false,
            // 独立日志级别
            'apart_level' => [],
            // 最大日志文件数量
            'max_files' => 30,
        ],
    ],
];

日志位置

默认在 runtime/log/ 目录下。

按日期分目录:

runtime/log/
├── 2026-10/
│   ├── 08.log
│   ├── 07.log
│   └── 06.log
└── 2026-09/
    └── ...

查看今天的错误

tail -f runtime/log/2026-10/08.log

四、常见500错误排查

1. 目录权限问题

runtime目录没权限写:

Permission denied

解决:

chmod -R 755 runtime
chown -R www:www runtime

2. 缺少扩展

Call to undefined function xxx()

解决: 装对应的PHP扩展。

3. 数据库连接失败

SQLSTATE[HY000] [1045] Access denied

检查: 数据库配置对不对。

.env 或 config/database.php:

'hostname' => '127.0.0.1',
'database' => '数据库名',
'username' => '用户名',
'password' => '密码',

4. 路由错误

Route not found

检查: 路由配置对不对。

5. 模板找不到

template not exists

检查: 模板文件路径对不对。

五、手动写日志

代码里可以手动写日志:

// 记录错误
Trace::error('这是一个错误信息');

// 记录警告
Trace::warning('这是一个警告');

// 记录信息
Trace::info('这是一个信息');

或者用助手函数:

trace('这是调试信息', 'debug');

六、查看PHP错误日志

除了ThinkPHP的日志,PHP本身也有错误日志。

查看PHP错误日志位置

php --ini | grep error_log

Nginx错误日志

tail -f /var/log/nginx/error.log

七、常见排查步骤

第一步:开debug看具体错误

改 .env:

APP_DEBUG = true

刷新页面,看具体报什么错。

第二步:看ThinkPHP日志

tail -f runtime/log/2026-10/08.log

第三步:看Nginx错误日志

tail -f /var/log/nginx/error.log

第四步:看PHP错误日志

tail -f /var/log/php-fpm/error.log

第五步:解决完改回debug

改完 .env:

APP_DEBUG = false

八、常见坑

坑1:开了debug还是不显示

缓存没清。

解决: 删除runtime目录下的缓存:

rm -rf runtime/cache/*

坑2:日志目录没权限

stream_socket_client(): unable to connect

runtime目录没写权限。

解决:

chmod -R 755 runtime

坑3:生产环境开着debug

危险!用户能看到你的敏感信息。

解决: 排查完立刻改回 APP_DEBUG = false。

坑4:日志太大占磁盘

日志越积越多,磁盘满了。

解决: 设 max_files,自动删除旧日志:

'max_files' => 30,

坑5:502和500搞混

  • 500:PHP代码错误
  • 502:PHP-FPM挂了

区分: 看Nginx错误日志。

总结

记住:

  1. 改 .env 的 APP_DEBUG = true 临时看错误
  2. 生产环境必须改回 false
  3. 日志在 runtime/log/ 目录
  4. 排查完记得清缓存
  5. 500是PHP代码问题,502是FPM问题

排查流程:

开debug → 看具体报错 → 看ThinkPHP日志 → 看Nginx日志 → 解决问题 → 关debug

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 08:31 

PHP FPM进程过多导致服务器卡顿优化 PHP

前言

PHP FPM进程太多,把服务器内存吃满,网站卡顿甚至502?本文讲怎么优化PHP FPM进程数。

一、为什么FPM进程多会卡

PHP FPM每处理一个请求,就开一个进程。

进程开多了:

  • 内存占满
  • CPU切换不过来
  • 服务器卡顿
  • 甚至OOM被杀

二、查看当前进程数

查看PHP FPM进程

ps aux | grep php-fpm

数一下有多少个进程。

看每个进程占多少内存

ps aux | grep php-fpm | awk '{print $6/1024 "MB"}'

算一下总内存

ps aux | grep php-fpm | awk '{sum+=$6} END {print sum/1024 "MB"}'

三、FPM配置文件在哪

CentOS

/etc/php-fpm.d/www.conf

或者:

/etc/php/7.4/fpm/pool.d/www.conf

Ubuntu

/etc/php/7.4/fpm/pool.d/www.conf

四、进程管理模式

PHP FPM有三种进程管理模式:

1. static(静态)

固定进程数,启动就开这么多。

pm = static
pm.max_children = 50

2. dynamic(动态)

默认模式,按需开进程。

pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35

3. ondemand

没人访问的时候不开进程,来了请求才开。

pm = ondemand
pm.max_children = 50
pm.process_idle_timeout = 10s

五、怎么算合适的进程数

公式

pm.max_children = 可用内存 / 每个进程平均内存

例子

  • 服务器2G内存
  • 系统和其他服务占1G
  • 剩下1G给PHP
  • 每个PHP进程平均占40M
pm.max_children = 1024 / 40 ≈ 25

所以设25个进程差不多。

别设太大

设太大了,内存不够用,就会OOM。

六、推荐配置

小服务器(1G内存)

pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 5

中服务器(2-4G内存)

pm = dynamic
pm.max_children = 30
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20

大服务器(8G以上)

pm = dynamic
pm.max_children = 80
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 40

七、其他优化参数

request_terminate_timeout

单个请求最长执行时间,超时就杀掉。

request_terminate_timeout = 30s

slow log

慢日志,看看哪个请求慢。

slowlog = /var/log/php-fpm/slow.log
request_slowlog_timeout = 10s

php_admin_value[memory_limit]

每个PHP进程的内存限制。

php_admin_value[memory_limit] = 128M

八、改完配置重载

systemctl reload php-fpm

或者:

systemctl restart php-fpm

九、验证效果

看进程数

ps aux | grep php-fpm | wc -l

看内存

free -h

看负载

top

十、常见坑

坑1:max_children设太大

比如2G内存设了100个进程,内存直接爆。

解决: 按上面的公式算,别拍脑袋。

坑2:改完配置不生效

忘了重载。

解决:

systemctl reload php-fpm

坑3:进程数一直涨

有慢请求,占着进程不放。

检查:

request_terminate_timeout = 30s

设个超时,超时就杀。

坑4:502 Bad Gateway

进程都忙不过来,Nginx连不上FPM。

解决: 加max_children,或者优化慢请求。

坑5:用了static模式

static固定进程数,不用就浪费内存。

推荐: 用dynamic或ondemand。

十一、排查步骤

第一步:看是不是FPM进程多

ps aux | grep php-fpm | wc -l

第二步:看内存够不够

free -h

第三步:看有没有慢请求

tail -f /var/log/php-fpm/slow.log

第四步:调整配置

改www.conf里的pm.max_children等参数。

第五步:重载验证

systemctl reload php-fpm

总结

记住:

  1. 进程数别设太大,按内存算
  2. 公式:可用内存 / 每个进程平均内存
  3. 推荐用dynamic模式
  4. 设个request_terminate_timeout,防慢请求占着进程
  5. 改完记得reload

推荐配置:

pm = dynamic
pm.max_children = 30
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
request_terminate_timeout = 30s

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-8 08:29 

PHP 字符串处理函数 PHP

PHP 字符串处理函数

字符串处理是 PHP 最常用的操作,这些函数一定要会。

1. 截取字符串

// 截取前n个字符
substr("hello world", 0, 5); // hello

// 中文截取(用mb_substr)
mb_substr("你好世界", 0, 2, "utf-8"); // 你好

2. 替换字符串

//  str_replace 替换
str_replace("world", "PHP", "hello world"); // hello PHP

// 只替换第一次出现
str_replace("a", "b", "aaa", $count);

3. 查找字符串

// 查找位置(找不到返回false)
strpos("hello world", "world"); // 6

// 注意:用 === 0 判断开头
if (strpos($str, "hello") === 0) {
    echo "以hello开头";
}

4. 大小写转换

// 转小写
strtolower("Hello"); // hello

// 转大写
strtoupper("hello"); // HELLO

// 首字母大写
ucfirst("hello"); // Hello

// 每个单词首字母大写
ucwords("hello world"); // Hello World

5. 去除空白

// 去除两边空格
trim("  hello  "); // hello

// 去左边
ltrim("  hello  "); // hello  

// 去右边
rtrim("  hello  "); //   hello

6. 字符串拼接

// 用点拼接
$str = "hello" . " " . "world";

// 多变量拼接
$a = "hello";
$b = "world";
$c = "$a $b"; // hello world

7. 分割和合并

// 分割成数组
$arr = explode(",", "a,b,c"); // ["a", "b", "c"]

// 数组合并成字符串
$str = implode(",", $arr); // a,b,c

8. 常用技巧

1)判断是否包含字符串:

if (strpos($str, "hello") !== false) {
    echo "包含hello";
}

2)反转字符串:

strrev("hello"); // olleh

3)字符串长度:

strlen("hello"); // 5
mb_strlen("你好", "utf-8"); // 2

总结

PHP 字符串处理要点:

  • substr 截取,注意中文用 mb_substr
  • str_replace 替换
  • strpos 查找,用 !== false 判断
  • trim 去空格
  • explode/implode 分割合并
  • 注意中文编码问题,用 mb 开头的函数

写 PHP,字符串函数天天用。


emer 发布于  2026-10-8 07:28 

PHP 常用设计模式 PHP

PHP 常用设计模式

设计模式是写好代码的经验总结,常用的几种要掌握。

1. 单例模式

整个项目只有一个实例,比如数据库连接。

class Db
{
    private static $instance = null;

    private function __construct() {}

    public static function getInstance()
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
}

$db = Db::getInstance();

2. 工厂模式

根据参数创建不同的对象。

class Factory
{
    public static function make($type)
    {
        $class = ucfirst($type);
        return new $class();
    }
}

$user = Factory::make('user');
$order = Factory::make('order');

3. 观察者模式

一个对象状态变化,通知所有观察者。

interface Observer
{
    public function update($event);
}

class Event
{
    private $observers = [];

    public function add(Observer $observer)
    {
        $this->observers[] = $observer;
    }

    public function trigger($event)
    {
        foreach ($this->observers as $ob) {
            $ob->update($event);
        }
    }
}

4. 常用场景

  • 单例: 数据库、日志、配置
  • 工厂: 创建不同类的对象
  • 观察者: 事件触发、消息通知
  • 策略: 不同支付方式
  • 适配器: 兼容不同接口

5. 设计原则

  • 单一职责:一个类只做一件事
  • 开闭原则:对扩展开放,对修改关闭
  • 依赖倒置:依赖抽象不依赖具体

总结

PHP 常用设计模式要点:

  • 单例模式:只创建一个实例
  • 工厂模式:统一创建对象
  • 观察者:事件通知
  • 理解设计原则
  • 不要为了模式而模式

设计模式是工具,解决问题才是目的。


emer 发布于  2026-10-8 07:24 

PHP Composer 使用指南 PHP

PHP Composer 使用指南

Composer 是 PHP 的依赖管理工具,做开发必备。

1. 安装 Composer

# 下载安装
curl -sS https://getcomposer.org/installer | php

# 移动到全局
mv composer.phar /usr/local/bin/composer

# 验证
composer -V

2. 国内镜像加速

# 阿里镜像
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

3. 常用命令

1)初始化项目:

composer init

2)安装依赖:

# 安装所有依赖
composer install

# 安装指定包
composer require monolog/monolog

# 安装开发依赖
composer require --dev phpunit/phpunit

3)更新依赖:

# 更新所有依赖
composer update

# 更新指定包
composer update monolog/monolog

4)删除依赖:

composer remove monolog/monolog

4. composer.json 说明

{
    "name": "test/project",
    "description": "测试项目",
    "require": {
        "php": ">=7.0",
        "monolog/monolog": "^2.0"
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

5. 自动加载

// 引入自动加载
require __DIR__ . '/vendor/autoload.php';

// 使用类
$log = new Monolog\Logger('name');

6. 常用操作

  • composer install:根据 lock 文件安装
  • composer update:更新依赖
  • composer dump-autoload:重新生成自动加载

总结

Composer 使用要点:

  • 安装 Composer
  • 配置国内镜像
  • require 安装依赖
  • autoload 自动加载
  • install/update 管理依赖

做 PHP 开发,Composer 一定要会用。


emer 发布于  2026-10-8 07:20 

PHP 会话管理详解 PHP

PHP 会话管理详解

Session 是 PHP 做用户登录状态管理的核心功能,搞懂它很重要。

1. 什么是 Session

  • Cookie: 存在客户端(浏览器)
  • Session: 存在服务器端
  • 通过 SessionID 关联用户

2. 基础用法

// 开启会话(必须放在最前面)
session_start();

// 存数据
$_SESSION['user_id'] = 1;
$_SESSION['username'] = "test";

// 取数据
echo $_SESSION['username'];

// 判断是否登录
if (isset($_SESSION['user_id'])) {
    echo "已登录";
} else {
    echo "未登录";
}

// 销毁会话
session_destroy();

3. 登录验证示例

// 登录页
session_start();

if ($_POST['password'] == "123456") {
    $_SESSION['user'] = $_POST['username'];
    header("Location: dashboard.php");
}

// 验证页
session_start();
if (!isset($_SESSION['user'])) {
    header("Location: login.php");
    exit;
}

4. 常用配置

php.ini 里的配置:

; 会话有效期(分钟)
session.gc_maxlifetime = 1440

; Cookie 有效期(秒)
session.cookie_lifetime = 0

; 是否只允许 HTTP 访问 Cookie
session.cookie_httponly = On

5. 常见问题

1)session 丢失:

  • 检查是否有输出(session_start 前不能有空格)
  • 检查 Cookie 是否被禁用

2)多服务器共享 Session:

  • 存在数据库里
  • 存在 Redis 里
  • 不要用文件 Session

3)安全问题:

  • 登录后重新生成 SessionID
    session_regenerate_id();
  • 防止 Session 固定攻击

6. Cookie vs Session

对比 Cookie Session
存储位置 客户端 服务器端
大小限制 4KB 无限制
安全性 低 高
生命周期 可长期保存 浏览器关闭就没了

7. 登出销毁

session_start();

// 清除所有 session 变量
$_SESSION = array();

// 清除 session cookie
if (isset($_COOKIE[session_name()])) {
    setcookie(session_name(), '', time()-42000, '/');
}

// 销毁 session
session_destroy();

总结

PHP 会话管理要点:

  • session_start() 必须在最前面
  • 登录验证用 $_SESSION 判断
  • 生产环境用 Redis 存 Session
  • 登录后重新生成 SessionID 防攻击

做用户系统,Session 是必须掌握的。


emer 发布于  2026-10-8 07:13 

PHP 错误处理机制 PHP

PHP 错误处理机制

做开发离不开错误处理,搞懂 PHP 的错误机制才能写出健壮的代码。

1. 错误级别

PHP 错误分几个级别:

1)致命错误(E_ERROR)

  • 脚本停止执行
  • 比如调用不存在的类、方法

2)警告(E_WARNING)

  • 脚本继续执行
  • 比如包含不存在的文件

3)注意(E_NOTICE)

  • 不影响执行
  • 比如使用未定义的变量

2. 错误报告配置

php.ini 里的配置:

; 开发环境:显示所有错误
display_errors = On
error_reporting = E_ALL

; 生产环境:不显示错误,记录日志
display_errors = Off
log_errors = On
error_reporting = E_ALL & ~E_NOTICE

3. 自定义错误处理

// 设置错误报告级别
error_reporting(E_ALL);

// 自定义错误处理函数
set_error_handler(function($errno, $errstr, $errfile, $errline) {
    echo "错误:[$errno] $errstr 在 $errfile 第 $errline 行";
    return true; // 阻止默认错误处理
});

// 测试
echo $undefined_var;

4. 异常处理

try {
    if (!file_exists("test.txt")) {
        throw new Exception("文件不存在");
    }
    $file = fopen("test.txt", "r");
} catch (Exception $e) {
    echo "错误:" . $e->getMessage();
} finally {
    echo "\n执行完成";
}

5. 错误日志

// 记录错误日志
error_log("这是一条错误日志", 3, "/tmp/php_errors.log");

// 手动触发错误
trigger_error("自定义错误", E_USER_WARNING);

6. 开发 vs 生产

开发环境:

  • 显示错误
  • 所有错误都报告
  • 方便调试

生产环境:

  • 不显示错误(防止泄露敏感信息)
  • 记录错误日志
  • 只报告致命错误和警告

7. 常用技巧

1)错误抑制符 @

// 不推荐,会影响性能
@include("config.php");

2)die/exit

// 简单粗暴
if (! $db) {
    die("数据库连接失败");
}

3)抛异常

  • 推荐用异常处理
  • 代码更清晰,容易维护

总结

PHP 错误处理要点:

  • 开发环境显示错误,生产环境记录日志
  • 用 try-catch 处理异常
  • 错误日志要记录,方便排查
  • 不要用 @ 错误抑制符

写代码多做错误处理,线上少踩坑。


emer 发布于  2026-10-8 07:09 

PHP 数组常用函数 PHP

PHP 数组常用函数

数组是 PHP 最常用的数据结构,数组函数用熟了开发效率翻倍。整理一份常用清单。

1. 数组创建和遍历

// 索引数组
$arr1 = [1, 2, 3];

// 关联数组
$arr2 = ['name' => '张三', 'age' => 25];

// 遍历
foreach ($arr2 as $key => $value) {
    echo "$key: $value\n";
}

2. 数组增删改查

// 追加元素
$arr[] = 4;
array_push($arr, 5, 6);

// 头部插入
array_unshift($arr, 0);

// 删除末尾元素
array_pop($arr);

// 删除头部元素
array_shift($arr);

// 删除指定元素
unset($arr[0]);

3. 数组合并和拆分

// 合并数组
$arr1 = [1, 2];
$arr2 = [3, 4];
$merged = array_merge($arr1, $arr2); // [1,2,3,4]

// 拆分
$slice = array_slice($arr, 0, 2);

4. 查找和过滤

// 判断键是否存在
array_key_exists('name', $arr);

// 判断值是否存在
in_array('张三', $arr);

// 查找值对应的键
array_search('张三', $arr);

// 数组过滤
$filtered = array_filter([1, 2, 3, 4], function($n) {
    return $n > 2;
}); // [3,4]

5. 排序

sort($arr);      // 升序
rsort($arr);     // 降序
asort($arr);     // 按值升序,保留键
ksort($arr);     // 按键升序

6. 常用操作

// 数组长度
count($arr);

// 去重
array_unique($arr);

// 反转
array_reverse($arr);

// 随机取一个
array_rand($arr);

7. 实际应用

统计数组中出现次数:

$counts = array_count_values(['a', 'b', 'a', 'c', 'a']);
// ['a' => 3, 'b' => 1, 'c' => 1]

二维数组按某列排序:

$users = [
    ['name' => '张三', 'age' => 25],
    ['name' => '李四', 'age' => 20]
];
array_multisort(array_column($users, 'age'), SORT_ASC, $users);

总结

PHP 数组函数非常多,日常开发记住这些常用的就够了:

  • 增删改查:array_push / array_pop / unset
  • 合并拆分:array_merge / array_slice
  • 查找过滤:in_array / array_filter
  • 排序:sort / asort / ksort

数组是 PHP 的灵魂,多用多练就熟了。


emer 发布于  2026-10-8 07:05 

PHP 错误处理最佳实践 PHP

PHP 错误处理最佳实践

错误处理是 PHP 开发最容易忽略但最重要的环节,写好了排查问题事半功倍,写不好线上出问题抓瞎。

1. 错误级别

PHP 有不同的错误级别:

  • E_ERROR:致命错误,脚本停止
  • E_WARNING:警告,脚本继续
  • E_NOTICE:注意,一般是不规范写法
  • E_PARSE:语法解析错误
// 开发环境显示所有错误
error_reporting(E_ALL);
ini_set('display_errors', 1);

// 生产环境不显示错误,只记日志
error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', '/var/log/php/error.log');

2. 错误 vs 异常

PHP 里错误和异常是两回事:

  • 错误:语法错误、内存不足这种,用 try/catch 抓不住
  • 异常:业务层面的错误,比如数据库连接失败

PHP 7+ 大部分错误会抛 Error 异常,也可以抓了。

3. try/catch 用法

try {
    // 可能出错的代码
    $pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
} catch (PDOException $e) {
    // 捕获异常
    echo "数据库连接失败:" . $e->getMessage();
    // 记日志
    error_log("DB Error: " . $e->getMessage());
}

4. 自定义错误处理

// 设置自定义错误处理器
set_error_handler(function($errno, $errstr, $errfile, $errline) {
    // 把错误转成异常抛出
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});

// 设置异常处理器
set_exception_handler(function($e) {
    // 所有未捕获的异常都到这里
    error_log("Uncaught: " . $e->getMessage());
    echo "系统繁忙,请稍后再试";
});

// 注册关闭函数,抓致命错误
register_shutdown_function(function() {
    $error = error_get_last();
    if ($error && in_array($error['type'], [E_ERROR, E_PARSE])) {
        error_log("Fatal: " . $error['message']);
    }
});

5. 开发 vs 生产环境

开发环境:

  • 打开 display_errors,错误直接显示在页面
  • 打开所有错误级别
  • 详细的报错信息方便调试

生产环境:

  • 关闭 display_errors,不要把错误暴露给用户
  • 错误全部写到日志文件
  • 页面显示友好的"系统错误"提示

6. 常用错误处理技巧

// 1. 用 @ 抑制错误不好,应该判断
// 不好:
$file = @file_get_contents('config.php');

// 好:
$file = file_exists('config.php') ? file_get_contents('config.php') : null;

// 2. 不要把数据库错误信息直接返回给前端
// 不好:
echo $e->getMessage();

// 好:
error_log($e->getMessage());
echo json(['code' => 500, 'msg' => '系统错误']);

// 3. 日志要分级
error_log('信息:用户登录', 3, '/var/log/info.log');
error_log('警告:登录失败次数过多', 3, '/var/log/warn.log');
error_log('错误:数据库连接失败', 3, '/var/log/error.log');

7. 总结

PHP 错误处理核心:

  • 开发环境显示错误,生产环境只记日志
  • try/catch 捕获业务异常
  • set_exception_handler 兜底
  • 不要把错误细节暴露给用户
  • 日志分级,方便排查

搞懂这些,线上出问题排查效率翻倍。


emer 发布于  2026-10-6 07:37 

PHP Composer 入门指南 PHP

PHP Composer 入门指南

Composer 是 PHP 的依赖管理工具,现在做 PHP 开发不用 Composer 几乎不可能。

1. 安装 Composer

# Linux/Mac
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

# Windows 直接下载安装包
# https://getcomposer.org/Composer-Setup.exe

验证安装:

composer -V

2. 换国内镜像(必须)

官方镜像太慢,一定要换国内镜像:

# 阿里云镜像
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

# 腾讯云镜像
composer config -g repo.packagist composer https://mirrors.tencent.com/composer/

3. 初始化项目

# 进入项目目录
cd myproject

# 初始化 composer.json
composer init

或者手动创建 composer.json:

{
    "name": "my/project",
    "require": {
        "monolog/monolog": "^2.0"
    }
}

4. 常用命令

# 安装依赖
composer install

# 更新依赖
composer update

# 安装某个包
composer require monolog/monolog

# 卸载某个包
composer remove monolog/monolog

# 自动加载
composer dump-autoload

5. 自动加载

// 引入自动加载文件
require __DIR__ . '/vendor/autoload.php';

// 然后就可以直接用第三方库了
$log = new Monolog\Logger('name');

6. composer.json 详解

{
    "name": "项目名",
    "description": "项目描述",
    "type": "project",
    "require": {
        "php": ">=7.4",
        "monolog/monolog": "^2.0",
        "guzzlehttp/guzzle": "^7.0"
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

7. 版本号说明

  • ^2.0:兼容 2.0 到 3.0(不包含 3.0)
  • ~2.0:兼容 2.0 到 2.1(不包含 2.1)
  • *:任意版本
  • 2.0.*:2.0.x 版本

总结

Composer 核心:

  • 安装:一行命令
  • 换镜像:必须换国内源
  • 常用:install / update / require / remove
  • 自动加载:require vendor/autoload.php

搞懂这些,Composer 日常开发就够用了。


emer 发布于  2026-10-4 11:06 

PHP 字符串处理技巧 PHP

PHP 字符串处理常用技巧

字符串处理是 PHP 开发最常用的操作,掌握这些函数,写代码效率翻倍。

1. 截取字符串

// 截取前 5 个字符
substr("hello world", 0, 5); // hello

// 截取从第 6 个开始到结尾
substr("hello world", 6); // world

// 中文字符串截取(用 mb_)
mb_substr("你好世界", 0, 2, "UTF-8"); // 你好

注意:中文要用 mb_substr,不能用 substr,否则会乱码。

2. 替换字符串

//  str_replace(替换所有)
str_replace("world", "PHP", "hello world"); // hello PHP

//  str_ireplace(不区分大小写)
str_ireplace("WORLD", "PHP", "hello world");

//  preg_replace(正则替换)
preg_replace("/\d/", "", "abc123def"); // abcdef

3. 查找字符串

// 查找位置(找不到返回 false)
strpos("hello world", "world"); // 6

// 查找最后出现位置
strrpos("hello world hello", "hello"); // 12

// 判断是否包含(PHP 8+)
str_contains("hello world", "world"); // true

// 判断开头
str_starts_with("hello world", "hello"); // true

// 判断结尾
str_ends_with("hello world", "world"); // true

4. 格式化字符串

// 去除首尾空格
trim("  hello  "); // hello

// 只去左边/右边
ltrim("  hello"); // hello
rtrim("hello  "); // hello

// 转小写/大写
strtolower("Hello"); // hello
strtoupper("hello"); // HELLO

// 首字母大写
ucfirst("hello"); // Hello

// 每个单词首字母大写
ucwords("hello world"); // Hello World

5. 字符串和数组转换

// 字符串转数组
explode(",", "a,b,c"); // ["a","b","c"]

// 数组转字符串
implode(",", ["a","b","c"]); // a,b,c

// 重复字符串
str_repeat("ab", 3); // ababab

// 字符串长度
strlen("hello"); // 5
mb_strlen("你好", "UTF-8"); // 2

6. 常用技巧

// 生成随机字符串
substr(md5(time()), 0, 8);

// 脱敏手机号
substr_replace("13812345678", "****", 3, 4); // 138****5678

// 截取摘要(带省略号)
mb_strlen($text) > 10 ? mb_substr($text, 0, 10) . "..." : $text;

// 清除 HTML 标签
strip_tags("<p>hello</p>"); // hello

总结

PHP 字符串处理核心函数:

  • 截取:substr / mb_substr
  • 替换:str_replace / preg_replace
  • 查找:strpos / str_contains
  • 格式化:trim / strtolower / ucwords
  • 转换:explode / implode

记住这些,日常开发基本够用了。


emer 发布于  2026-10-4 11:04 

PHP 数组操作技巧 PHP

PHP 数组操作技巧

数组是 PHP 最常用的数据结构,掌握这些技巧,写代码效率翻倍。

1. 数组合并

// 索引数组合并
$arr1 = [1, 2];
$arr2 = [3, 4];
$result = array_merge($arr1, $arr2); // [1,2,3,4]

// 关联数组合并,后面覆盖前面
$arr1 = ['a' => 1, 'b' => 2];
$arr2 = ['b' => 3, 'c' => 4];
$result = array_merge($arr1, $arr2); // ['a'=>1, 'b'=>3, 'c'=>4]

2. 数组去重

// 一维数组去重
$arr = [1, 2, 2, 3, 3, 3];
$result = array_unique($arr); // [1,2,3]

// 二维数组按字段去重
$users = [
    ['id' => 1, 'name' => '张三'],
    ['id' => 2, 'name' => '李四'],
    ['id' => 1, 'name' => '张三'],
];
$ids = array_column($users, 'id');
$unique = array_unique($ids);

3. 数组排序

// 升序
sort($arr);

// 降序
rsort($arr);

// 按键排序
ksort($arr);

// 按值排序,保留键
asort($arr);

4. 数组过滤

// 过滤空值
$arr = [1, 0, '', null, 'a'];
$result = array_filter($arr); // [1, 'a']

// 自定义过滤
$result = array_filter($arr, function($value) {
    return $value > 2;
});

5. 数组取值

// 取某一列
$names = array_column($users, 'name');

// 取交集
$arr1 = [1, 2, 3];
$arr2 = [2, 3, 4];
$result = array_intersect($arr1, $arr2); // [2,3]

// 取差集
$result = array_diff($arr1, $arr2); // [1]

6. 常用技巧

// 判断键是否存在
isset($arr['key']);
array_key_exists('key', $arr);

// 随机取一个
$value = array_rand($arr);

// 打乱数组
shuffle($arr);

// 数组合并成字符串
$str = implode(',', $arr);

// 字符串转数组
$arr = explode(',', $str);

总结

PHP 数组函数非常丰富,常用的就这些:合并、去重、排序、过滤、取值。把这些记熟,日常开发基本够用了。


emer 发布于  2026-10-4 10:48 

PHP 安全最佳实践 PHP

PHP 开发必须注意的安全问题

PHP 开发最容易出安全问题,几个常见坑一定要避开。

1. SQL 注入

最常见的安全漏洞。用户输入拼接到 SQL 里,被注入恶意 SQL。

解决方案:用预处理语句

// 不要这样
$sql = "SELECT * FROM users WHERE id = " . $_GET['id'];

// 要这样
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_GET['id']]);

2. XSS 跨站脚本

用户输入直接输出到页面,被注入恶意 JS。

解决方案:输出时转义

echo htmlspecialchars($user_input);

3. CSRF 跨站请求伪造

别人伪造你的请求操作。

解决方案:加 Token 验证

// 表单里加 Token
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['token']; ?>">

// 后端验证
if ($_POST['csrf_token'] !== $_SESSION['token']) {
    die('CSRF 攻击');
}

4. 文件上传漏洞

用户上传 PHP 文件,直接拿到 webshell。

解决方案:

  • 限制文件类型
  • 重命名文件
  • 上传目录不执行 PHP

5. 密码明文存储

数据库被拖库,密码全泄露。

解决方案:用 password_hash

$hash = password_hash($password, PASSWORD_DEFAULT);

// 验证
password_verify($password, $hash);

6. 错误信息泄露

生产环境把报错直接展示给用户,暴露路径和代码。

解决方案:关闭 display_errors

display_errors = Off
log_errors = On

总结

PHP 安全的核心:用户输入都不可信,所有输出都要转义,数据库操作用预处理。安全开发意识比工具更重要。


emer 发布于  2026-10-4 10:37 

PHP 8.0 新特性 PHP

PHP 8.0 有哪些重磅更新

PHP 8.0 是一个大版本更新,带来了很多革命性的特性。

1. JIT 编译

PHP 8.0 引入了 JIT(即时编译),性能大幅提升,计算密集型场景性能翻倍。

2. 命名参数

array_filter(array: $array, callback: fn($x) => $x > 0);

不用按顺序传参,写参数名就行,可读性更好。

3. 枚举 Enum

enum Status: string
{
    case Pending = 'pending';
    case Active = 'active';
    case Rejected = 'rejected';
}

4. 构造函数属性提升

class User {
    public function __construct(
        public int $id,
        public string $name
    ) {}
}

不用再写 $this->id = $id 了,构造函数直接定义属性。

5. 空安全运算符

$user?->getAddress()?->city;

不用层层判断 null,有 null 直接返回 null。

6. Match 表达式

$result = match($status) {
    200 => '成功',
    404 => '未找到',
    default => '未知'
};

比 switch 更简洁,还能直接赋值。

7. 联合类型

function foo(int|string $input) {}

参数可以是多种类型。

总结

PHP 8.0 是现代 PHP 的起点,类型系统更完善,语法更现代。新项目强烈推荐用 PHP 8.0+。


emer 发布于  2026-10-4 10:34 

PHP 7.4 新特性 PHP

PHP 7.4 有哪些实用新特性

PHP 7.4 是 7.x 系列的最后一个版本,带来了不少语法糖和性能优化,至今还有很多项目在用。

1. 类型属性

类的属性可以声明类型了:

class User {
    public int $id;
    public string $name;
    public ?string $email;
}

之前属性不能写类型,只能靠 PHPDoc 注释,现在直接写在代码里,IDE 提示更准确。

2. 箭头函数

支持短闭包:

$users = array_map(fn($user) => $user['name'], $users);

比传统的 function ($user) use (...) {} 简洁多了,自动捕获外层变量。

3. 空合并赋值

$data['user'] ??= [];

相当于:

if (!isset($data['user'])) {
    $data['user'] = [];
}

4. 数组展开

$arr1 = [1, 2, 3];
$arr2 = [4, 5, 6];
$merged = [...$arr1, ...$arr2];

5. 数字字面量分隔

$amount = 1_000_000;
$price = 9_999.99;

大数字用下划线分隔,可读性提升。

6. 性能提升

PHP 7.4 比 7.3 性能提升约 10%,内存占用也更少。

总结

PHP 7.4 虽然不是大版本,但实用特性很多,尤其是类型属性和箭头函数,写起来舒服不少。新项目建议直接上 PHP 8+,老项目升级到 7.4 也很稳妥。


emer 发布于  2026-10-4 10:27 

PHP Session 与 Cookie:会话管理实战指南 PHP

前言

HTTP 是无状态的,你每次请求服务器都不认识你。Session 和 Cookie 就是用来解决这个问题的。本文讲清楚 PHP 中 Session 和 Cookie 的用法。

一、Cookie 是什么

Cookie 是存在浏览器里的小数据,每次请求自动带给服务器。

设置 Cookie

setcookie("username", "张三", time() + 3600, "/");

参数说明:

  • 第一个参数:名称
  • 第二个参数:值
  • 第三个参数:过期时间(时间戳)
  • 第四个参数:路径

读取 Cookie

echo $_COOKIE['username'];

删除 Cookie

setcookie("username", "", time() - 3600, "/");

把过期时间设成过去就行。

二、Session 是什么

Session 是存在服务器上的数据,通过 Session ID 识别用户。

启动 Session

session_start();

注意:必须在输出之前调用,不然会报错。

存数据

$_SESSION['user_id'] = 1;
$_SESSION['username'] = '张三';

读数据

echo $_SESSION['username'];

删除单个数据

unset($_SESSION['user_id']);

销毁 Session

session_destroy();

三、Session 和 Cookie 的区别

对比 Cookie Session
存储位置 浏览器 服务器
大小限制 4KB 无限制
安全性 低(用户能改) 高
生命周期 可设置 默认浏览器关闭就没

四、登录功能示例

登录页

<?php
session_start();

if ($_POST) {
    $username = $_POST['username'];
    $password = $_POST['password'];

    // 验证用户名密码
    if ($username == 'admin' && $password == '123456') {
        $_SESSION['user_id'] = 1;
        $_SESSION['username'] = $username;
        header('Location: dashboard.php');
        exit;
    } else {
        echo "用户名或密码错误";
    }
}
?>

判断是否登录

<?php
session_start();

if (!isset($_SESSION['user_id'])) {
    header('Location: login.php');
    exit;
}
?>

退出登录

<?php
session_start();
session_destroy();
header('Location: login.php');
exit;
?>

五、Session 配置

修改 Session 有效期

ini_set('session.gc_maxlifetime', 3600); // 1小时
session_start();

修改 Session 存储路径

session_save_path('/tmp/sessions');
session_start();

用 Redis 存储 Session

生产环境推荐用 Redis 存 Session,默认文件存储性能差。

php.ini 配置:

session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"

六、安全问题

1. Session 劫持

别人拿到你的 Session ID,就能冒充你。

防护:

  • 用 HTTPS
  • Session ID 定期更换
  • 绑定 IP(不太推荐,IP 会变)

2. Cookie 劫持

别人拿到你的 Cookie,就能冒充你。

防护:

  • 设置 HttpOnly,JS 读不到
  • 设置 Secure,只在 HTTPS 下传
  • 设置 SameSite,防止 CSRF
setcookie("token", $token, [
    'expires' => time() + 3600,
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Strict'
]);

3. CSRF 攻击

别人伪造你的请求。

防护:

  • 表单加 CSRF Token
  • 验证 Referer

七、常见坑

  1. session_start() 在输出之后:报错 headers already sent
  2. Session 没销毁:退出登录后还能访问
  3. Cookie 大小限制:别存太多东西,超过 4KB 就丢
  4. Session 文件太多:默认文件存储,大了要清理

八、最佳实践

  1. 敏感数据用 Session,别存 Cookie
  2. Cookie 加 HttpOnly 和 Secure
  3. 生产环境用 Redis 存 Session
  4. 登录成功后重新生成 Session ID,防止固定攻击
// 登录成功后
session_regenerate_id(true);

总结

Session 和 Cookie 的核心要点:

  1. Cookie 存在浏览器,Session 存在服务器
  2. session_start() 必须在输出之前调用
  3. Session 更安全,Cookie 更轻量
  4. 生产环境用 Redis 存 Session
  5. Cookie 加 HttpOnly 和 Secure,防劫持

登录、权限、购物车,都离不开 Session 和 Cookie。搞懂这俩,PHP 后端才算入门。


emer 发布于  2026-10-4 10:21 

PHP Composer 入门:依赖管理完全指南 PHP

前言

Composer 是 PHP 的依赖管理工具,就像 Node 的 npm、Python 的 pip。现在写 PHP 项目,不会 Composer 根本没法干活。本文讲清楚 Composer 的核心用法。

一、安装 Composer

Linux / Mac

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

Windows

去官网下载安装包,一路下一步就行。

验证安装

composer -V

二、初始化项目

# 在项目目录下
composer init

会问你几个问题,一路回车就行,然后会生成 composer.json 文件。

composer.json 长什么样

{
    "name": "yourname/project",
    "description": "项目描述",
    "require": {
        "monolog/monolog": "^2.0"
    }
}

三、安装依赖

1. 安装所有依赖

composer install

会根据 composer.lock 文件安装指定版本的依赖。

2. 添加新依赖

composer require monolog/monolog

会自动加到 composer.json 里,然后安装。

3. 安装指定版本

composer require monolog/monolog:^2.0

版本号说明

  • ^2.0:2.0 到 3.0 之前(不包括 3.0)
  • ~2.0:2.0 到 2.1 之前(不包括 2.1)
  • *:任意版本
  • 2.0.*:2.0 开头的版本

四、自动加载

Composer 最爽的就是自动加载,不用自己写 require。

引入自动加载

<?php
require 'vendor/autoload.php';

// 直接用类,不用 require
$log = new Monolog\Logger('name');

PSR-4 自动加载

在 composer.json 里配置:

{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

然后执行:

composer dump-autoload

这样 App\User 类就会从 src/User.php 加载。

五、常用命令

命令 作用
composer install 安装所有依赖
composer update 更新所有依赖
composer require 包名 添加依赖
composer remove 包名 删除依赖
composer dump-autoload 重新生成自动加载
composer show 查看已安装的包
composer self-update 更新 Composer 本身

六、开发环境依赖

有些包只在开发时用,比如测试工具:

composer require --dev phpunit/phpunit

线上部署的时候,不安装开发依赖:

composer install --no-dev

七、中国镜像

国外源太慢,换中国镜像:

# 阿里云镜像
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

# 腾讯云镜像
composer config -g repo.packagist composer https://mirrors.tencent.com/composer/

换完之后速度飞起来。

八、composer.lock 的作用

  • 记录当前安装的依赖版本
  • 团队成员 install 的时候,装的版本一模一样
  • 一定要提交到 Git
git add composer.json composer.lock
git commit -m "update composer"

九、常见坑

  1. 没装 composer.lock:团队成员装的版本不一样,出 bug
  2. 自动加载不生效:改了 autoload 配置,忘了 dump-autoload
  3. 版本冲突:两个包依赖同一个库的不同版本
  4. 国内太慢:不换镜像,下载半天

十、最佳实践

  1. composer.json 和 composer.lock 都提交 Git
  2. 线上用 install --no-dev,不要用 update
  3. 用中文镜像,加速下载
  4. 改了自动加载配置,记得 dump-autoload

总结

Composer 的核心要点:

  1. require 添加依赖,install 安装依赖
  2. vendor/autoload.php 是自动加载入口
  3. composer.lock 要提交 Git,保证版本一致
  4. 换国内镜像,速度快很多
  5. 开发依赖用 --dev,线上不装

学会 Composer,PHP 开发效率提升一倍。


emer 发布于  2026-10-4 10:20 

PHP 数组常用操作:从排序到过滤的完整指南 PHP

前言

数组是 PHP 里最常用的数据结构,没有之一。PHP 提供了 100 多个数组函数,很多人只知道其中几个。本文整理最常用的数组操作。

一、创建数组

<?php
// 索引数组
$arr1 = [1, 2, 3, 4, 5];

// 关联数组
$arr2 = ['name' => '张三', 'age' => 18];

// 空数组
$arr3 = [];

二、添加元素

<?php
$arr = [1, 2, 3];

// 末尾添加
$arr[] = 4; // [1, 2, 3, 4]
array_push($arr, 5); // [1, 2, 3, 4, 5]

// 开头添加
array_unshift($arr, 0); // [0, 1, 2, 3, 4, 5]

// 关联数组添加
$user = ['name' => '张三'];
$user['age'] = 18; // ['name' => '张三', 'age' => 18]

三、删除元素

<?php
$arr = [1, 2, 3, 4, 5];

// 删除末尾元素
array_pop($arr); // [1, 2, 3, 4]

// 删除开头元素
array_shift($arr); // [2, 3, 4]

// 删除指定元素
unset($arr[1]); // [0 => 2, 2 => 4],注意索引不连续

四、查找元素

<?php
$arr = ['a', 'b', 'c'];

// 值是否存在
in_array('b', $arr); // true

// 键是否存在
$user = ['name' => '张三', 'age' => 18];
array_key_exists('name', $user); // true

// 查找值的键
array_search('b', $arr); // 1

五、数组长度

<?php
$arr = [1, 2, 3];
count($arr); // 3
sizeof($arr); // 3(count 的别名)

六、排序

索引数组排序

<?php
$arr = [3, 1, 2, 5, 4];

sort($arr); // [1, 2, 3, 4, 5] 升序
rsort($arr); // [5, 4, 3, 2, 1] 降序

关联数组排序

<?php
$age = ['张三' => 20, '李四' => 18, '王五' => 25];

asort($age); // 按值升序,保持键名
ksort($age); // 按键升序
arsort($age); // 按值降序
krsort($age); // 按键降序

自定义排序

<?php
$users = [
    ['name' => '张三', 'age' => 20],
    ['name' => '李四', 'age' => 18],
    ['name' => '王五', 'age' => 25],
];

// 按 age 升序
usort($users, function ($a, $b) {
    return $a['age'] <=> $b['age'];
});

七、数组过滤

array_filter()

<?php
$arr = [1, 2, 3, 4, 5, 6];

// 过滤出偶数
$even = array_filter($arr, function ($n) {
    return $n % 2 == 0;
});
// [2, 4, 6]

array_map()

<?php
$arr = [1, 2, 3, 4, 5];

// 每个元素乘以 2
$doubled = array_map(function ($n) {
    return $n * 2;
}, $arr);
// [2, 4, 6, 8, 10]

array_walk()

<?php
$arr = ['a' => 1, 'b' => 2];

array_walk($arr, function (&$value, $key) {
    $value = $value * 10;
});
// ['a' => 10, 'b' => 20]

八、数组合并

<?php
$arr1 = [1, 2];
$arr2 = [3, 4];

// 数组合并
$merged = array_merge($arr1, $arr2); // [1, 2, 3, 4]

// + 运算符(保留第一个数组的键)
$result = $arr1 + $arr2;

九、数组切片

<?php
$arr = [1, 2, 3, 4, 5];

// 从第 2 个开始取 3 个
$slice = array_slice($arr, 1, 3); // [2, 3, 4]

// 从末尾取
$last = array_slice($arr, -2); // [4, 5]

十、键值操作

<?php
$user = ['name' => '张三', 'age' => 18];

// 所有键
array_keys($user); // ['name', 'age']

// 所有值
array_values($user); // ['张三', 18]

// 翻转键值
array_flip($user); // ['张三' => 'name', 18 => 'age']

十一、常用操作速查表

操作 函数
数组长度 count()
查找值 in_array()
查找键 array_key_exists()
排序 sort() / asort() / ksort()
过滤 array_filter()
映射 array_map()
合并 array_merge()
切片 array_slice()

十二、常见坑

  1. unset 后索引不连续:用 array_values() 重新索引
  2. array_merge 和 + 的区别:数字键 array_merge 会重新索引,+ 不会
  3. in_array 严格模式:加第三个参数 true 防止类型转换
  4. sort 会改变原数组:不是返回新数组

总结

PHP 数组操作的核心要点:

  1. 增删改查:array_push/pop/unshift/shift/unset
  2. 查找判断:in_array/array_key_exists/array_search
  3. 排序:sort/asort/ksort/usort
  4. 处理:array_filter/array_map/array_walk
  5. 合并切片:array_merge/array_slice

数组用好了,PHP 开发效率能提升一倍。


emer 发布于  2026-10-4 10:15 

PHP 字符串处理:常用函数和最佳实践指南 PHP

前言

字符串处理是 PHP 开发中最常用的操作之一。很多人写了很多年代码,却还是用错字符串函数。本文整理最常用的字符串处理函数和最佳实践。

一、字符串长度

strlen()

<?php
$str = "hello";
echo strlen($str); // 5

注意:strlen 按字节算,中文会出问题。

mb_strlen()

<?php
$str = "你好";
echo mb_strlen($str, 'UTF-8'); // 2
echo strlen($str); // 6(3个字节一个汉字)

记住:处理中文一定要用 mb_ 系列函数。

二、字符串查找

strpos()

查找字符串第一次出现的位置:

<?php
$str = "hello world";
$pos = strpos($str, "world");
echo $pos; // 6

坑: 如果没找到返回 false,如果找到的位置是 0,也返回 0。

<?php
// 错误写法
if (strpos($str, "hello")) {
    // 如果 hello 在第 0 位,这里不会执行
}

// 正确写法
if (strpos($str, "hello") !== false) {
    // 这样才对
}

strrpos()

查找字符串最后一次出现的位置。

stripos() / strripos()

不区分大小写的查找。

三、字符串替换

str_replace()

<?php
$str = "hello world";
echo str_replace("world", "PHP", $str); // hello PHP

数组替换:

<?php
echo str_replace(
    ["hello", "world"],
    ["hi", "PHP"],
    "hello world"
); // hi PHP

substr_replace()

替换字符串的一部分:

<?php
echo substr_replace("hello world", "PHP", 6); // hello PHP

preg_replace()

正则替换:

<?php
// 把多个空格变成一个
echo preg_replace('/\s+/', ' ', "hello   world"); // hello world

四、字符串截取

substr()

<?php
$str = "hello world";
echo substr($str, 0, 5); // hello
echo substr($str, 6); // world

中文截取要用 mb_substr():

<?php
$str = "你好世界";
echo mb_substr($str, 0, 2, 'UTF-8'); // 你好

五、字符串分割与连接

explode()

<?php
$str = "a,b,c,d";
$arr = explode(",", $str);
print_r($arr); // ['a', 'b', 'c', 'd']

implode() / join()

<?php
$arr = ['a', 'b', 'c'];
echo implode(",", $arr); // a,b,c

六、字符串去空格

trim()

<?php
$str = "  hello  ";
echo trim($str); // "hello",去掉两边空格
echo ltrim($str); // "hello  ",去掉左边空格
echo rtrim($str); // "  hello",去掉右边空格

七、大小写转换

<?php
$str = "Hello World";
echo strtolower($str); // hello world
echo strtoupper($str); // HELLO WORLD
echo ucfirst($str); // Hello world
echo ucwords($str); // Hello World

八、HTML 转义

htmlspecialchars()

输出到 HTML 时一定要转义,防止 XSS:

<?php
$str = "<script>alert('xss')</script>";
echo htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
// 输出 &lt;script&gt;alert(&#039;xss&#039;)&lt;/script&gt;

htmlentities()

更彻底的转义,把所有 HTML 都转义。

九、JSON 处理

json_encode()

<?php
$arr = ['name' => '张三', 'age' => 18];
echo json_encode($arr, JSON_UNESCAPED_UNICODE);
// {"name":"张三","age":18}

记住:加 JSON_UNESCAPED_UNICODE,不然中文会变成 \uXXXX。

json_decode()

<?php
$json = '{"name":"张三","age":18}';
$obj = json_decode($json); // 对象
$arr = json_decode($json, true); // 数组

十、常见坑

  1. strpos 用 == 判断:位置 0 和 false 会混淆
  2. 中文用 strlen/substr:按字节算,中文会乱码
  3. 输出 HTML 不转义:XSS 漏洞
  4. json_encode 不加 JSON_UNESCAPED_UNICODE:中文变 \uXXXX
  5. 字符串拼接用 . 不用 +:PHP 是 . 号

总结

PHP 字符串处理的核心要点:

  1. 中文用 mb_ 系列函数,不要用 strlen/substr
  2. strpos 用 !== false 判断,不要用 ==
  3. 输出 HTML 一定要 htmlspecialchars 转义
  4. json_encode 加 JSON_UNESCAPED_UNICODE
  5. 字符串拼接用 . 号,不要用 + 号

掌握这些,字符串处理就不会出大问题了。


emer 发布于  2026-10-4 10:12 
'); })();