PHP检查文件是否存在

PHP检查文件是否存在

引言

上传头像、读取配置、缓存命中判断之前,都要先确认文件是否存在。PHP里file_exists判断文件或目录,is_file专门判断普通文件,is_dir判断目录,三者语义不同,用错会把目录当成文件导致后续读取报错。

file_exists 判断存在

$path = './config/config.php';
if (file_exists($path)) {
    echo '文件存在';
} else {
    echo '文件不存在';
}

文件或目录存在都返回true,路径不存在、权限不可访问返回false。

is_file 判断是普通文件

if (is_file($path)) {
    echo '这是一个普通文件';
}

目录、符号链接、管道都返回false,读取文件前用它最稳妥。

is_dir 判断目录

$dir = './uploads';
if (is_dir($dir)) {
    echo '目录存在';
}

专门判断目录,适合上传前检查目录是否已建。

判断可读性再操作

if (is_file($path) && is_readable($path)) {
    $content = file_get_contents($path);
}

存在不代表可读,权限不足时file_get_contents会警告,先加is_readable判断。

路径拼接注意

$file = __DIR__ . '/../data/' . $name;

用绝对路径拼接,避免相对路径受当前工作目录影响,跨目录包含时不容易找错文件。

注意事项

  • file_exists缓存了文件状态,删改文件后可用clearstatcache清缓存;
  • 判断普通文件用is_file,别只靠file_exists,目录会误判;
  • 检查存在后还要is_readable/is_writable,权限是另一道关;
  • 文件名含中文或特殊字符注意编码统一,避免误判不存在;
  • 防路径穿越,用户传入的文件名先过滤..和绝对路径;
  • 大量循环判断文件时注意stat缓存带来的性能影响。

总结

file_exists判断文件或目录是否存在,is_file判断普通文件,is_dir判断目录,is_readable/is_writable判断读写权限。读取配置、上传文件、缓存命中前先做存在性和权限判断。注意clearstatcache清理状态缓存,用户传入文件名要防路径穿越,跨目录用DIR拼绝对路径,避免相对路径偏移导致找错文件。


emer 发布于  2026-10-22 07:10 

PHP获取文件扩展名

PHP获取文件扩展名

引言

文件上传、附件处理、图片裁剪时都要先拿到后缀判断类型。别用explode切字符串硬切,pathinfo是PHP专门解析路径的函数,能干净返回扩展名、文件名、目录名各部分。

pathinfo 标准用法

$file = '/var/www/upload/photo.2024.jpg';
$info = pathinfo($file);
echo $info['extension'];   // jpg
echo $info['filename'];    // photo.2024
echo $info['dirname'];     // /var/www/upload

一次返回路径各组成部分,最稳妥。

只取扩展名

$ext = pathinfo($file, PATHINFO_EXTENSION);
// jpg

传第二个常量直接拿扩展名,省一次数组取值。

处理无扩展名文件

$ext = pathinfo('README', PATHINFO_EXTENSION);
// 空字符串,不会报错

没扩展名时返回空串,记得做空判断。

大写转小写统一

$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));

用户传JPG、Jpg、jpg都归一,上传校验用统一小写比较。

不要用explode硬切

// 反面例子:photo.2024.jpg 会切错
$parts = explode('.', $file);
$ext = end($parts);

多级点号文件名会取错,pathinfo按最后一个点正确取后缀。

注意事项

  • 扩展名不等于真实MIME类型,校验文件内容要用finfo;
  • 扩展名可伪造,上传安全不能只信后缀;
  • PATHINFO_EXTENSION对".htaccess"这种点开头文件返回空;
  • 中文文件名不受影响,pathinfo按字节正确处理;
  • 取到扩展名后trim并strtolower再做白名单校验;
  • 别把扩展名当安全依据,配合大小限制和重命名存储。

总结

pathinfo($file, PATHINFO_EXTENSION)取扩展名最稳,filename拿文件名、dirname拿目录,无扩展名返回空串记得判断,业务里统一strtolower小写。不要用explode切多级点号文件名。扩展名只是展示用,真实类型靠finfo判断,上传安全还需白名单加文件内容校验和重命名存储。


emer 发布于  2026-10-21 07:01 

PHP文件上传校验

PHP文件上传校验

引言

文件上传是网站高频功能,也是最容易出安全问题的地方。只判断后缀名,黑客可以把木马改名为图片绕过,上传到服务器执行。上传必须做多层校验。

必须校验的内容

  1. 检查上传错误码,确认文件确实上传成功;
  2. 限制文件大小,防止超大文件占满磁盘;
  3. 白名单校验扩展名,只允许jpg/png等指定类型;
  4. 读取文件真实MIME类型,不能只信前端传的type;
  5. 重新生成随机文件名,避免原文件名覆盖或路径穿越;
  6. 上传目录禁止执行PHP脚本。

基础校验示例

<?php
$allow = ['jpg','png','gif'];
$ext = strtolower(pathinfo($_FILES['file']['name'],PATHINFO_EXTENSION));
if(!in_array($ext,$allow)){
    exit('类型不允许');
}
if($_FILES['file']['size'] > 2*1024*1024){
    exit('文件过大');
}
//获取真实类型
$info = getimagesize($_FILES['file']['tmp_name']);
if(!$info) exit('不是合法图片');
//随机重命名
$newName = uniqid().'.'.$ext;
move_uploaded_file($_FILES['file']['tmp_name'],'./upload/'.$newName);

服务端加固

  • Nginx/Apache配置上传目录禁止解析php;
  • 图片上传后重新压缩生成,破坏木马脚本;
  • 关闭上传目录的执行权限;
  • 定期扫描上传目录文件。

总结

文件上传安全核心:不信任前端、白名单、校验真实类型、随机改名、目录隔离。多层校验才能防止webshell上传,保护服务器安全。


emer 发布于  2026-10-18 07:19 

Linux上传下载文件,rz和sz命令使用

前言

经常需要从本地电脑上传文件到服务器,或者把服务器上的文件下载到本地。除了用 FTP 工具,还有更简单的 rz 和 sz 命令,直接在终端里就能操作。本文讲一下怎么用。

安装 lrzsz

rz 和 sz 命令来自 lrzsz 包,CentOS 最小化安装可能没有:

yum install -y lrzsz

Ubuntu 的话:

apt install -y lrzsz

rz 上传文件(从本地上传到服务器)

基本用法

直接输入:

rz

执行后会弹出一个文件选择窗口,选你要上传的文件,点确定就开始上传了。

注意: 文件会上传到你当前所在的目录。

指定文件名

上传后直接改成指定名字:

rz -y 新文件名

-y 是覆盖同名文件。

上传多个文件

执行 rz 之后在文件选择窗口可以按住 Ctrl 多选。

sz 下载文件(从服务器下载到本地)

下载单个文件

sz 文件名

比如下载 index.html:

sz index.html

执行后会弹出保存窗口,选保存位置就开始下载了。

下载多个文件

sz 文件1 文件2 文件3

比如:

sz a.txt b.txt c.txt

下载整个目录(先打包)

sz 不能直接下载目录,要先打包:

tar -zcvf backup.tar.gz /var/www/html
sz backup.tar.gz

常见使用场景

场景1:上传配置文件

# 先进入要上传的目录
cd /etc/nginx/conf.d/

# 上传
rz

选本地的 nginx 配置文件,上传完就直接放到这个目录了。

场景2:下载日志文件

# 进入日志目录
cd /var/log/nginx/

# 下载访问日志
sz access.log

场景3:上传压缩包

本地把项目打包成 zip,然后:

cd /var/www/html/
rz

选本地的项目 zip 文件,上传完再解压。

常见坑

坑1:rz 命令找不到

执行 rz 提示 command not found。

原因: 没装 lrzsz 包。

解决:

yum install -y lrzsz

坑2:上传的文件不知道去哪了

执行了 rz,但不知道文件上传到哪了。

原因: 文件上传到你当前所在的目录。

解决: 上传前先 pwd 看一下当前目录在哪。

坑3:用了某些 SSH 工具不支持 rz/sz

有些 SSH 客户端(比如 Windows 自带的 cmd)不支持 rz/sz。

原因: rz/sz 需要终端支持 ZModem 协议。

解决: 用支持的 SSH 工具,比如 Xshell、SecureCRT、FinalShell、MobaXterm。

坑4:大文件上传慢

上传几百 M 的文件特别慢。

原因: rz/sz 走的是 SSH 通道,速度不快。

解决: 大文件用 SFTP 或者专门的传输工具(FileZilla)更快。

坑5:上传的文件是乱码

上传完中文文件名变成乱码。

原因: 编码问题。

解决: 用英文文件名,或者先打包成 zip 再上传。

总结

命令 作用
rz 从本地上传文件到服务器
sz 文件名 从服务器下载文件到本地

前提: 要先装 lrzsz 包,而且 SSH 工具要支持 ZModem 协议。

小文件用 rz/sz 很方便,大文件还是用 SFTP 吧。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 08:01 
'); })();