【问题标题】:Getting an image to render with php使用 php 获取要渲染的图像
【发布时间】:2015-09-02 20:45:10
【问题描述】:

为简单起见,我尝试使用 php 显示图像以帮助 try 并防止任何类型的安全漏洞。我有通过 php 脚本读取的图像,我想渲染它,所以我不想去http://example.com/path/to/uploads/dir/image.jpg,我想让用户能够去http://example.com/path/to/script/image1,让他们能够看到图像。

这样我可以将图像路径 (http://example.com/path/to/uploads/dir/) 隐藏在我的文档根目录之外(到域路径无法直接访问的位置)。因此,如果域的路径是 /path/to/public_html/,那么我希望将图像上传到 /path/to/uploads/,这样您在浏览我的域时就无法导航到上传目录。

我的问题是我一直在尝试渲染的图像,无法渲染,我不确定为什么。 MD5 校验和相同,HTTP 标头也相似。图像的direct path 与图像的desired path 相比。

我使用 Laravel 作为框架/主干,但我认为这并不重要,我渲染图像的代码如下

public function getImage($id){
  $img = TitanImage::findOrFail($id);
//  header('Content-type: image/jpeg');
//  header('Content-Length: ' . filesize($img->path));
//  header('Accept-Ranges: bytes');
//  echo file_get_contents($img->path);
  $file = $img->path;
  $type = 'image/jpeg';
  header('Content-Type:'.$type);
  header('Content-Length: ' . filesize($file));
  readfile($file);
//  exit();
  return;
}

我还使用webconfs 来检查所需图像端点的标头。

编辑 1

关于intervention/image 包的其中一个cmets,我更改了代码,但仍然得到相同的结果;但是,内容长度发生了变化,变得更长了。

public function getImage($id){
  $img = TitanImage::findOrFail($id);
//  header('Content-type: image/jpeg');
//  header('Content-Length: ' . filesize($img->path));
//  header('Accept-Ranges: bytes');
  $file = $img->path;
  return Image::make(trim($file,' '))->response();
}

编辑 2

在此编辑中,@Digitlimit 提到了检查图像是否存在。这是我当前的代码。

public function getImage($id){
  $img = TitanImage::findOrFail($id);
  $file = $img->path;
  if(file_exists($file))
    return Image::make($file)->response('jpg');
  else
    return 'File doesnt exist';
}

我也做了测试,看看如果我只返回 $file 而不是 Image::make 实例会发生什么,我得到了正确的路径,即。当我通过 SSH 进入服务器并将 cd 转到路径减去图像名称时,路径存在并且具有权限。当我执行ls -la 命令时,它会列出图像并且它也具有适当的权限。

【问题讨论】:

  • 术语错误。 “在我的领域之后”。它应该在“我的文档根目录之外”。
  • 为什么不使用超棒的干预图像。请参阅类似问题的答案:stackoverflow.com/questions/30875139/…
  • @Digitlimit 我更新了我的代码,我仍然没有改变,我也更新了问题。
  • 您安装了干预镜像吗?如果是,您需要创建一条路线。另请说明您的图片所在位置
  • 我按照intervention.io网站上的说明,创建了一个路由,根据存储在数据库中的路径检索图像,这是我问题中的代码。我正在制作图像并返回响应。

标签: php image laravel image-processing


【解决方案1】:

如果您已安装干预映像,请执行以下操作:

public function getImage($id){
  $img = TitanImage::findOrFail($id);
  $file = $img->path;
  return Image::make($file)->response('jpg');
}

编辑: 我在我的项目中对此进行了测试,它运行良好:

路线:

Route::get('/api/v1/titan/image/{id}',function($id){
    return \Image::make(storage_path("/images/$id.jpg"))->response('jpg');
});

图片在我的项目中的位置:

访问 URL 时的输出:http://laravel.dev/api/v1/titan/image/1

铬元素检查

【讨论】:

  • 这正是我正在做的。在我的中,我只是确保没有空格。
  • 图片路径错误或无效。我将包含代码来检查文件是否存在。还要确保您启用了 GD 扩展
  • 我编辑了我的问题,包括检查文件是否存在。我还确认 GD 扩展已启用。
  • 我可以看看你得到的输出吗?
  • 你想要什么输出?
【解决方案2】:

代码正在运行 - 问题在于它发送了额外信息。文件那里,找到,正在发送。返回图片的链接:

HTTP/1.1 200 OK
Date: Wed, 17 Jun 2015 22:52:03 GMT
Server: Apache
Connection: close
Content-Type: image/jpeg

但是后面的输出错误

00000050  3a 20 63 6c 6f 73 65 0d  0a 43 6f 6e 74 65 6e 74  |: close..Content|
00000060  2d 54 79 70 65 3a 20 69  6d 61 67 65 2f 6a 70 65  |-Type: image/jpe|
00000070  67 0d 0a 0d 0a 20 ff d8  ff e1 19 57 45 78 69 66  |g.... .....WExif|
                         ^^
                           `this 20 here, before the ff d8 ff of JPEG.

所以这段代码(只负责JPEG部分)是可以的。

public function getImage($id){
  $img    = TitanImage::findOrFail($id);
  $file   = $img->path;
  if (file_exists($file)) {
      return Image::make($file)->response('jpg');
  }
  else {
    return "File doesn't exist";
  }
}

数据流开头的额外空格可能来自一些 PHP 文件,在开始 <?php 标记之前或可能在结束标记之后有一个额外的空格。

对于后者,建议您不要关闭<?php标签,即永远不要包含“?>”序列。

对于前者,请尝试

public function getImage($id) {
    return "*** is there a space before the asterisks?";
}

并观察返回的 HTML。除非错误出现在 TitanImage 中,我认为这不太可能,否则您应该在 JPEG 图像之前发送的星号之前看到相同的空间。定义getImage() 函数的文件很可能是可疑文件。

否则,您可以运行“grep”来查找<?php 开头的PHP 文件。您可以通过将-v 标志添加到grep 来修改此shameless plug

【讨论】:

  • 我会在明天回到项目工作后尝试这个,并告诉你结果。
  • 我刚刚仔细检查了 Titan 项目的每个文件,你知道什么。我的路线文件中在<?php 之前有一个空格我真的要感谢@Iserni。
  • 不客气。如果你知道它发生在我身上多少次... :-D
猜你喜欢
  • 2014-12-14
  • 2012-09-19
  • 2012-06-17
  • 1970-01-01
  • 1970-01-01
  • 2015-06-28
  • 2015-09-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多