PHP file_put_contents:无法打开流:权限被拒绝

PHP file_put_contents:无法打开流:权限被拒绝

我想使用 PHP 存储图像,因此我使用以下代码:

$encodedCard = isset($_POST["card"])? $_POST["card"] : null;
        $name = isset($_POST["fn"]) ? $_POST["fn"] : null;
        $card = base64_decode($encodedCard,true);
        $completePath = '/home/user/cards/' . $name . '.png';
        if (file_put_contents($completePath, $card)!== false) {
            echo "success";
        } else {
            $lastError = error_get_last();
            echo "Error writing to file: " . $lastError['message'];
        }

我已经检查过代码直到该if语句为止都运行正常。

我收到以下错误:

Error writing to file: file_put_contents(/home/user/cards/image_name.png): Failed to open stream: Permission denied

打开我的 Aapche2 error.log 后,出现以下内容:

PHP Warning: file_put_contents(/home/user/cards/image_name.png): Failed to open stream: Permission denied in /path/to/the/php/file.php on line 5

我尝试更改目录的权限,但没有任何效果。我尝试的更改如下:

## did not work
chmod -R 755 /home/user/cards/
## did not work
chown -R www-data:www-data /home/user/cards/
## did not work
chmod -R 777 /home/user/cards/

如果有帮助的话,我在 Ubuntu 22.04.03 LTS 机器上使用 Apache2 作为服务器。

任何帮助都值得赞赏;提前致谢。

编辑:在 Dorg 回答之后,我添加了一些与我的 Apache 2 配置文件相关的信息。

我将 PHP 文件保存为/var/www/domain_name/api/add/image.php

我的虚拟主机如下:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName domain_name
    ServerAlias domain_name
    DocumentRoot /var/www/domain_name
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

尽管我的虚拟主机中没有它<Directory>,但我的文件中却有它apache.conf

<Directory />
    Options FollowSymLinks
    AllowOverride None
    Require all denied
</Directory>

<Directory /usr/share>
    AllowOverride None
    Require all granted
</Directory>

<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

<Directory /home/user/cards/>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

答案1

不需要权限问题基于文件系统权限(但有可能)。

Apache 有一个内部权限系统,您必须在 Apache 的(虚拟)主机配置或.htaccess文件结构中的文件中进行配置。

最好在(虚拟)主机的 Apache 配置中声明如下内容:

<Directory /home/user/cards/>
    Require all granted
</Directory>

或者,如果允许此类文件,您可以将设置放在.htaccess文件中:

文件:/home/user/cards/.htaccess

Require all granted

也许你想阅读更多.htaccess关于Apache 文档以便更好地微调您网站的权利。


更新 1

感谢您的更新。

  1. .htaccess您的配置不允许。
  2. 配置应该可以允许访问这些文件。
  3. 如果您对 Apache 配置进行了任何更改,请记住必须重新启动 Apache 服务才能使更改生效:
    apachectl restart
    

我看到你的 VirtualHost 配置

DocumentRoot /var/www/domain_name

并比较组装的路径:

$completePath = '/home/user/cards/' . $name . '.png';

这个差异暴露了问题的所在:最终目的地并不在之内DocuemntRoot


您应该创建一个符号/var/www/domain_name链接/home/user/cards/

ln -s /home/user/cards  /var/www/domain_name/cards

并更改为$completePath使用这个符号链接:

$completePath = '/var/www/domain_name/cards/' . $name . '.png'

Web 客户端的最终 URLDocumentRoot /var/www/domain_name现在位于:

http://domain_name/cards/image_name.png

请注意,在 中设置的权限 <Directory /home/user/cards/>不会对路径 生效/var/www/domain_name/cards/
但 Apache 将根据父级定义授予访问权限:

<Directory /var/www/>
    [...]
    Require all granted
</Directory>

答案2

查看 apache 以哪个用户身份运行

ps 辅助 | grep httpd

我相信默认情况下这将是“无人”(但请使用你找到的)

sudo chown 没人/路径...

相关内容