thinkphp5 中mkdir 没有权限 出现Permission denied

本文探讨了在使用ThinkPHP5框架过程中遇到的mkdir() Permission denied错误,并提供了两种解决方案:一是给予runtime目录最大权限;二是更改runtime目录的所有者为web服务器用户。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近一直在用tp5写项目,在此遇到的问题也比较多。今天来谈谈“mkdir() Permission denied”错误。

你如果不仅仅写代码,还得部署到线上,那么这个tp5的这个错误,你有很大概率会遇见它。

因为这跟文件的权限有关系,特别是自动生成的文件或者目录类的权限,linux服务器出于安全因素对于用户的权限有着严格的控制。

对于tp框架而言,自动生成的文件或者目录应该是runtime目录,所以在线部署代码的时候,开放此类目录的权限。

所以解决mkdir() premission denied 的问题最直接的方式,把runtime权限放开,让所有用户都可以创建它。

chmod -R 777 runtime

在liunx中进入项目目录执行以上命令,就能解决这个问题,简单,高效。

如果你对文件的安全要求比较苛刻,那么以上的答案并不能令你满意,简单,高效的方法背后一般需要牺牲一些安全因素为代价。

但以下提供的方法或许是一个不错的选择。

更改runtime目录的所有者,也就是runtime这个目录权限只针对所有者开放。

以我的项目为例,服务器是nginx,nginx中设置的访问用户为www用户,那么我只需要把runtime目录有root用户改为www用户就能解决此问题。

ps aux|grep nginx //查看当前的nginx进程,能够找到nginx用户是哪个(可能是www,user或者其他的)

chown -R www runtime //chown -R <nginx 用户> runtime,改变runtime所有者为nginx用户

ok,进入项目目录去执行上面的命令吧,是否有效一试便知。

上面的方法的解释是因为对于web的每一个请求都是由服务器(nginx,apache等)代劳的,真正操作这些项目文件或目录的是这些服务器用户,比如nginx中的www用户,apache中的apache用户。所以指定文件或者目录的所有者就是这个问题的关键,至于第一个方法设置最高权限为何也可以呢,这个就相当于任何用户都能访问这个runtime目录,当然也包括www或者apache用户。退一步,上面的第二个方法是以nginx为例,如果你的服务器是apache呢,那你现在应该知道怎么改了吧。

如果上面按照上面的步骤还是没有搞定,接着继续

1. 查看SELinux状态
1.1 getenforce
getenforce 命令是单词get(获取)和enforce(执行)连写,可查看selinux状态,与setenforce命令相反。
setenforce 命令则是单词set(设置)和enforce(执行)连写,用于设置selinux防火墙状态,如: setenforce 0用于关闭selinux防火墙,但重启后失效

[root@localhost ~]# getenforce
Enforcing
1.2 /usr/sbin/sestatus
Current mode表示当前selinux防火墙的安全策略

[root@localhost ~]# /usr/sbin/sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      28
SELinux status:selinux防火墙的状态,enabled表示启用selinux防火墙
Current mode: selinux防火墙当前的安全策略,enforcing 表示强

2. 关闭SELinux
2.1 临时关闭
setenforce 0 :用于关闭selinux防火墙,但重启后失效。

[root@localhost ~]# setenforce 0
[root@localhost ~]# /usr/sbin/sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   permissive
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      28
2.1 永久关闭
修改selinux的配置文件,重启后生效。

打开 selinux 配置文件
[root@localhost ~]# vim /etc/selinux/config
修改 selinux 配置文件
将SELINUX=enforcing改为SELINUX=disabled,保存后退出

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of three two values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected. 
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted
此时获取当前selinux防火墙的安全策略仍为Enforcing,配置文件并未生效。

[root@localhost ~]# getenforce
Enforcing
重启
[root@localhost ~]# reboot
验证
[root@localhost ~]# /usr/sbin/sestatus
SELinux status:                 disabled

[root@localhost ~]# getenforce
Disabled

### 解决Apache运行ThinkPHP项目时因权限问题导致`mkdir()`报错的问题 在Linux环境下,当使用Apache运行ThinkPHP项目时,可能会因为文件或目录的权限不足而导致`mkdir()`函数调用失败,并抛出`Permission denied`错误。以下是针对该问题的专业解决方案: #### 1. 权限分配的核心原因 此问题的根本原因是Web服务器进程(如Apache)无法获取足够的权限来创建新目录或写入数据。通常情况下,Apache以特定用户身份运行,默认可能是`www-data`(Debian/Ubuntu系统)或`apache`(CentOS/RHEL系统)。因此,确保目标目录及其父级目录具有适当的所有权和读写权限至关重要[^2]。 #### 2. 修改目录所有权 将项目的存储目录(通常是`runtime`或其他需要动态生成内容的目录)的所有者更改为Apache使用的用户。例如,在基于Debian的系统中,可以执行以下命令: ```bash sudo chown -R www-data:www-data /path/to/project/runtime/ ``` 而在RedHat系发行版上则应替换为相应的用户名: ```bash sudo chown -R apache:apache /path/to/project/runtime/ ``` #### 3. 设置合适的权限位 除了改变所有者外,还需要赋予适当的权限以便允许写入操作而不开放过多的安全风险。推荐做法是仅给予所属组写权限而非全局范围内的完全控制: ```bash find /path/to/project/runtime/ -type d -exec chmod 750 {} \; find /path/to/project/runtime/ -type f -exec chmod 640 {} \; chmod g+s /path/to/project/runtime/ ``` 上述命令分别设置了目录与普通文件的不同访问级别,并启用了setgid标志使得新建子项继承相同的群组归属关系。 #### 4. SELinux策略调整 (适用于某些严格安全配置场景) 如果操作系统启用了SELinux,则可能进一步限制了即使拥有正确Unix层面上权限也无法完成的操作。此时可通过临时禁用来排查是否为此因素引起干扰: ```bash setenforce 0 ``` 长期解决办法涉及定义自定义policy modules或者标记相关路径为httpd_sys_rw_content_t类型标签之一。具体实施细节取决于实际环境复杂度及合规性要求[^1]。 #### 5. 验证改动后的效果 完成上述步骤后重新加载网页界面观察现象变化情况。另外还可以手动模拟触发同样的动作序列来进行独立测试验证目的达成状况良好与否。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值