php 在 public 目录外调用 php 文件作为图像

php call php file as image outside public directory

在 public 目录之外的目录 privadimgdir 中,我有文件 create_img.php 可以动态创建 png 图像。我需要从 public 目录之外提供该 img 以避免其他站点直接访问输出图像。

为此,我正在尝试使用 php 代理脚本。在 public_scripts 目录中,我有文件 take_img.php,代码如下:

<?php

$file_to_get = basename(urldecode($_GET['file']));

$private_image_dir = "../../privateimgdir/";

$contents = file_get_contents($private_image_dir . $file_to_get);

header('Content-type: image/png');

echo $contents;

?>

现在我尝试调用 take_img.php 脚本并使用以下代码将 create_img.php 文件名作为参数传递:

echo "<a href='public_scripts/take_img.php?file=create_img.php'></a>";

但我没有得到任何输出。我哪里错了?

几件事:

1) file_get_contents 不会实际执行您的 PHP,它只会 return 来自该文件的原始源代码作为字符串。您希望使用 includerequire 使脚本成为主脚本的一部分,从而被解析和执行。

2) 不要直接通过 $_GET 参数接受文件名 - 这存在安全风险。它允许用户潜在地在您的系统上执行任意脚本。即使您正在对您的用户进行身份验证,您也不能相信任何给定的用户不是恶意的,也不是某种身份盗用、社会工程、and/or virus/malware/bot 在其设备上的受害者。

这里有一个解决方案,您可以在 GET 参数中传递任意 ID,这样会更安全,因为您可以将允许的选项列入白名单,并且仍然允许您选择要执行的正确脚本。

首先,您的 HTML link 标签将如下所示:

<a href='public_scripts/take_img.php?id=1'></a>

take_img.php 看起来像这样:

<?php

$id = $_GET['id'];
$private_image_dir = "../../privateimgdir/";
$script = "";

switch ($id) {
  case 1:
    $script = "create_img.php";
    break;
  case 2:
    $script = "someotherscript.php";
    break;
  case 3:
    $script = "yetanotherscript.php";
    break;
  default:
    throw new Exception("Invalid ID");
}

header('Content-type: image/png');
require_once $private_image_dir.$script;

?>

(N.B。假定包含的 PHP 脚本将回显内容。)