在平常的PHP开发工作里头,标记着的目录权限错误,算得上是极为常见的一类环境方面的问题。

不少开发者,特别是才开始接触服务器配置的友人,常常会碰到“无法将文件写入”、“无法把目录创建”或者干脆是“服务器出现500错误的状况”。

十有八九,这些问题是,由于PHP进程用户,像那个www-data,对目标目录,在读写权限方面没能拥有正确的权限所致的。

要是不把控系统的排查以及处理办法,仅仅只是猜测权限究竟是755还是777,那就足够令人头疼了。

今日,我们着手详尽梳理PHP目录权限错误的处理流程,还要探究怎样于代码层面生成清晰且易于理解的报错提示,以此便利自身及队友对问题进行定位。

利用函数精准检查目录权限

在动手修改权限之前,第一步必须是精准地“诊断”。

PHP内置了两个非常实用的函数来帮我们检查目录的权限状态。

$dir = '/path/to/dir';
if (is_readable($dir)) {
    // 有读取权限,进行后续操作
} else {
    // 没有读取权限,处理错误
}

能对当前PHP进程有没有读取该目录的权限行判断的函数是is_readable()

若是给出的返回结果为false,这样的情况便表明,我们是没有办法去读取这个目录之中的文件列表的,自然而然地,必定也是无法开展后续的打开或者读取文件的相关操作的。

它的使用方式极为径直,仅仅只需将目录路径传进去就行,就像这样,is_readable('/var/www/uploads')

与之对应的函数is_writable()用来进行判断,看看当时对于进程说起来讲,依据是当前进程,它有没有权限,能够朝着这个目录里面去写入数据,像创设新的 файл文件呀、变更修改 файл文件等等方面的操作行为呢。

$dir = '/path/to/dir';
if (is_writable($dir)) {
    // 有写入权限,进行后续操作
} else {
    // 没有写入权限,处理错误
}

要是这两个函数之中有一个返回了假值,那就表明目录权限的确是存在着问题,这是需要进一步去进行处理的。

这两个函数所返回的,是布尔值,极为可靠,是我们于代码里面展开权限自检时的第一道防线。

修改目录权限的常用操作

在我们对目录权限存在问题予以确认以后,最为直接的解决办法便是去修改目录的权限模式。

在PHP中,我们可以使用chmod()函数来完成这个操作。

需留意的是,此函数的第二个参数,即权限模式,它是一个八进制数,在直接书写数字时,其前面务必得加上0。

例如,最为常用的那个0755,它所代表的是,文件所有者具备读写以及执行的权限,然而,其他的人仅仅只有读和执行的权限,这属于是绝大多数安全要求比较高的生产环境所推荐的设置。

其中,0777虽说权限是最大的,任何的人都能够有读写的权利,然而出于安全方面的考量,除非是处于极其特殊并且能够确保绝对安全的内网环境之中,不然的话是不建议进行使用的。

$dir = '/path/to/dir';
$mode = 0777;
if (chmod($dir, $mode)) {
    // 修改权限成功
} else {
    // 修改权限失败,处理错误
}

发起调用的示例呈现为,chmod('/var/www/uploads', 0755)

如果修改成功,函数会返回true,否则返回false。

这个操作一般来讲,得是PHP进程自身,对这个目录具备所有权,才能够成功,要是连所有者权限都达不到要求,那种情况下,或许就得依靠系统命令行,或者宝塔面板之类的工具,来进行提升了。

目录不存在时的处理方案

php目录权限错误处理方法_is_readable和is_writable函数使用_PHP权限错误

程序报错“无法打开目录”,有时出现了:“无法写入文件”,这情况不一定是权限方面的问题了,而是目录压根就不存在。

这种情况下,我们需要的不是修改权限,而是创建目录。

PHP的mkdir()函数就是专门干这个的。

它接纳三个参数,头一个是目录路径,第二个是权限模式,而第三个是个布尔值,此布尔值用以判定是否去创建多级目录~

像这样,mkdir,它的参数是 '/var/www/html/data/cache',还有 0755,以及 true

在此处将第三个参数设定为true极具实用性,其能够自动以递归方式创建所有并不存在的上级目录,这便规避了需一层一层通过手工去创建的那种麻烦。

创建成功返回true,失败则返回false。

于实际开发之际,我们习惯于先判定目录是否存在,倘若不存在便尝试去创建,要是创建呈现失败之状抑或是创建完成后仍旧不能够写入,那就开展权限检查以及修改了。

抛出异常以便调试定位

$dir = '/path/to/dir';
$mode = 0777;
if (mkdir($dir, $mode, true)) {
    // 创建目录成功
} else {
    // 创建目录失败,处理错误
}

将权限以及目录存在性的问题于代码层面予以解决之后,我们仍需对“用户体验”与“调试体验”展开思索。

要是操作出现失败的情况,不能够使得程序直接去抛出一个属于Warning级别的错误,或者直接呈现为白屏状态,如此这般既不具备友好性,也对快速定位没有益处。

比较规范的做法是抛出异常

我们能够结合先前提及的检查函数,在is_writable()返回为false之际,主动运用throw new Exception('目录不可写,请检查权限:' . $dirPath);去中断程序的执行,进而给出清晰的提示。

在更为高级的框架里头,我们能够搭配try-catch结构去捕获这个异常,还能于日志当中记录详尽的错误信息,与此同时朝着前端用户传回一个友善的提示,像“系统临时目录配置异常,请联系管理员”。

输出直观的错误信息

在一些简单脚本之时,于调试阶段,除了采取抛出异常这种相对“重型”的方式以外,直接输出错误信息亦是一种较为快速且效果显著的手段。

在使用 mkdir()fopen() 等函数失败之后,我们能够借助 error_get_last() 函数去获取最后一轮所出现的错误详情,或者直接把 error_get_last() 里的信息进行整合,通过 echo 或者 print 将确切的错误缘由打印至屏幕上。

例如“创建目录失败,请检查上级目录权限”。

此种做法具备的好处在于直观,它格外适宜于在本地开发环境之时,或者在排查问题之际进行临时运用。

$dir = '/path/to/dir';
if (!is_readable($dir)) {
    throw new Exception("目录没有读取权限");
}

但是需要留意,处于生产环境之时,这般详细的错误信息应当被记载至日志文件当中,而并非直接提供给最终使用用户,如此以避免将服务器路径这样的敏感信息给暴露出来。

PHP目录权限错误予以处理时,存在一连串固定的流程:先是借助is_readable()以及is_writable()来开展诊断,接着依据具体情形运用chmod()去着手进行权限的修改,或者借助mkdir()来完成目录的创建,最终以抛出异常或者记录日志的形式生成明晰的报错反馈。

掌握了这套方法,以后遇到类似问题就不会手忙脚乱了。

$dir = '/path/to/dir';
if (!is_writable($dir)) {
    echo "目录没有写入权限";
}