在平常的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的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 "目录没有写入权限";
}

Comments NOTHING