常用运行时配置

<?php
declare(strict_types=1); // 开启严格类型


//========== 报告所有错误·用于开发环境 ==========//
ini_set('display_errors', 'On'); // 开启打印错误信息
ini_set('error_reporting', E_ALL); // 报告所有级别错误
ini_set('display_startup_errors', 'On'); // 显示启动过程中的错误
ini_set('log_errors', 'Off'); // 不记录脚本运行错误
ini_set('error_log', null); // 脚本运行错误日志文件(若不存在会自动创建)
//========== 屏蔽所有错误·用于生产环境 ==========//
ini_set('display_errors', 'Off'); // 关闭打印错误信息
ini_set('error_reporting', E_ALL & ~E_DEPRECATED & ~E_STRICT); // 报告部分级别错误
ini_set('display_startup_errors', 'Off'); // 不显示启动过程中的错误
ini_set('log_errors', 'On'); // 记录脚本运行错误
ini_set('error_log', __DIR__ . '/error.log'); // 脚本运行错误日志文件(若不存在会自动创建)
// 说明①:error_log不仅会记录错误(不管是致命错误还是非致命错误),也会记录异常。
// 说明②:若一台服务器上有多个项目,建议每个项目都各自指定error_log以方便管理,而不是使用php.ini的全局error_log。
// 说明③:虽然PHP自带记录错误日志功能,但还是强烈建议使用set_error_handler()和register_shutdown_function()注册错误处理函数,
//         这种方式同样可以记录错误信息,而且更加灵活,譬如当程序发生错误时可以给管理员发邮件或短信,从而可以第一时间处理错误。


//========== 脚本执行限制相关 ==========//
PHP_SAPI !== 'cli' && exit('脚本只能在命令行执行');
ini_set('max_execution_time', 30); // 设置脚本最大执行时间,单位为秒,若设置为0则不限制
ini_set('memory_limit', '128M'); // 允许脚本分配的最大内存量,以字节为单位,若设置为-1则不限制
//========== 脚本执行限制相关(适合CLI模式) ==========//
PHP_SAPI !== 'cli' && exit('脚本只能在命令行执行');
ini_set('max_execution_time', 0);
ini_set('memory_limit', '-1');


//========== SESSION相关 ==========//
ini_set('session.save_handler', 'files'); // 设置SESSION保存方式
ini_set('session.save_path', __DIR__ . '/session_save'); // 设置SESSION保存目录
ini_set('session.name', 'PHPSESSID'); // 设置SESSION名称
session_status() === PHP_SESSION_NONE && session_start(); // 启动SESSION


//========== OPcache相关 ==========//
if (extension_loaded('Zend OPcache')) {
    ini_set('opcache.enable', '0'); // 重要提醒:使用ini_set()函数只能禁用操作码缓存,不能启用操作码缓存,否则报Warning
    ini_set('opcache.validate_timestamps', '1'); // 自动刷新缓存,可选值:0=关闭|1=开启,该配置会影响下面的opcache.revalidate_freq配置
    ini_set('opcache.revalidate_freq', '2'); // 自动刷新缓存频率(单位为秒),该配置仅在“opcache.validate_timestamps=1”时有意义
    ini_set('opcache.jit', 'tracing'); // 是否启用JIT,PHP官方推荐使用“tracing”
}
// 说明:OPcache相关配置的可修改范围大多是INI_SYSTEM,可以使用ini_set()修改的配置并不多。


//========== 其它设置 ==========//
ini_set('date.timezone', 'Asia/Shanghai'); // 设置默认时区为中国标准时间(北京时间)


//========== 自定义响应头 ==========//
header('Server: Tomcat');
header('X-AspNetMvc-Version: 4.0');
header('X-AspNet-Version: 4.0.30319');
header('X-Powered-By: ASP.NET');


//========== 自动加载注册 ==========//
spl_autoload_register(static function (string $class): bool {
    $exists = false;

    // 引入 *.class.php 文件(注:如果类名包含命名空间可能需要额外处理,这里略过)
    $filename = __DIR__ . "/$class.class.php";
    if (file_exists($filename)) {
        require_once $filename;
        $exists = class_exists($class);
    }

    // 引入 *.model.php 文件
    if (!$exists) {
        $filename = __DIR__ . "/$class.model.php";
        if (file_exists($filename)) {
            require_once $filename;
            $exists = class_exists($class);
        }
    }

    return $exists;
});


//========== 错误接管·非致命错误 ==========//
$callable = set_error_handler(
    static function (int $errno, string $errstr, string $errfile, int $errline): bool {
        $errors = [];
        $errors[E_ERROR] = 'Error'; // E_ERROR = 1: int
        $errors[E_WARNING] = 'Warning'; // E_WARNING = 2: int
        $errors[E_PARSE] = 'Parse'; // E_PARSE = 4: int
        $errors[E_NOTICE] = 'Notice'; // E_NOTICE = 8: int
        $errors[E_CORE_ERROR] = 'Core Error'; // E_CORE_ERROR = 16: int
        $errors[E_CORE_WARNING] = 'Core Warning'; // E_CORE_WARNING = 32: int
        $errors[E_COMPILE_ERROR] = 'Compile Error'; // E_COMPILE_ERROR = 64: int
        $errors[E_COMPILE_WARNING] = 'Compile Warning'; // E_COMPILE_WARNING = 128: int
        $errors[E_USER_ERROR] = 'User Error'; // E_USER_ERROR = 256: int
        $errors[E_USER_WARNING] = 'User Warning'; // E_USER_WARNING = 512: int
        $errors[E_USER_NOTICE] = 'User Notice'; // E_USER_NOTICE = 1024: int
        $errors[E_STRICT] = 'Strict'; // E_STRICT = 2048: int
        $errors[E_RECOVERABLE_ERROR] = 'Recoverable Error'; // E_RECOVERABLE_ERROR = 4096: int
        $errors[E_DEPRECATED] = 'Deprecated'; // E_DEPRECATED = 8192: int
        $errors[E_USER_DEPRECATED] = 'User Deprecated'; // E_USER_DEPRECATED = 16384: int
        $errors[E_ALL] = 'All'; // E_ALL = 32767: int

        $errtype = $errors[$errno] ?? "Unknown($errno)";

        // 仿照标准错误处理程序的格式输出错误信息(可将错误信息写入错误日志文件)
        echo "$errtype: $errstr in $errfile on line $errline";

        return true; // 不再调用标准错误处理程序
        // return false; // 继续调用标准错误处理程序
    }, E_ALL
);


//========== 错误接管·致命错误 ==========//
register_shutdown_function(static function (): void {
    $error = error_get_last(); // 若无错误则返回null
    if (is_array($error) && isset($error['type'])) {
        // 仿照标准错误处理程序的格式输出错误信息(可将错误信息写入错误日志文件)
        echo "Fatal error: {$error['message']} in {$error['file']} on line {$error['line']}";
    }
});


exit('OK');


//========== 总结 ==========//
// 1、不是所有的配置项都能用ini_set()动态修改,只有可修改范围是PHP_INI_USER或PHP_INI_ALL的配置项才能用ini_set()动态修改,
//    例如和上传文件限制相关的upload_max_filesize、post_max_size都属于PHP_INI_PERDIR,所以它们都不能用ini_set()动态修改。
//    配置选项及可修改范围列表:https://www.php.net/manual/zh/ini.list.php

Copyright © 2024 码农人生. All Rights Reserved