Cakephp3: Return image content from controller

behavior

#1

I have an application made in cakephp3 and I want to load the images directly from the controller, with a url like user/photo/{id}.

      public function foto($id)
    {
      $usuario = $this->Usuario->get($id);
      $foto = $usuario['foto'];
      if (strpos($foto, "base64")===false) {
          $content = file_get_contents($foto,FILE_BINARY);
        $format=  getimagesize($foto);
        $this->autoRender = false;
        $this->response->type($format['mime']);

        $this->response->body($content);
      }
      else{
        $array = explode(":",$foto);
        $type = explode(";",$array[1])[0];
        $type = explode("/",$type)[1];

        $data = explode( ',', $foto );

        $this->autoRender = false;
        $this->response->type($type);
        $source = ( base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $foto)));
        $this->response->body($source);
      }
      //
      return $this->response;

    }

Today, I have two cases of uploads: one by external url, and the other by base64 encoded image
First case:

  $content = file_get_contents($foto,FILE_BINARY);
    $format=  getimagesize($foto);
    $this->autoRender = false;
    $this->response->type($format['mime']);

    $this->response->body($content);

Second Case:

$array = explode(":",$foto);
    $type = explode(";",$array[1])[0];
    $type = explode("/",$type)[1];

    $data = explode( ',', $foto );

    $this->autoRender = false;
    $this->response->type($type);
    $source = ( base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $foto)));
    $this->response->body($source);

The problem is that none of them works. Both return a empty image. How do I get the images to load correctly?


#2

Are you using CakePHP 3.4?

If the answers is yes, then response is immutable, so this code takes no effect.

you would have to make something like this:

$this->response = $this->response->withFile(base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $foto))); return $this->response;


#3

Im using CakePHP 3.3.16


#4

Then try the code below, then:

$this->response->file(base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $foto)));
return $this->response;

not shure if it works with base64 though
before CakePHP 3.4 i used to do something like this:

public function loadImage()
{
    if(empty($this->request->params['id'])) {
        throw new NotFoundException();
    }
    $file = $this->Files->get($this->request->params['id']);
    $image = $this->loadimageSize($file, $this->request->params['imgSize']);
    $this->response->header('Content-Type', $file->mime_type);
    $this->response->header('Content-Length', filesize($image));
    readfile($image);
    die();
}

maybe you could replace the readfile('image') by base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $foto)) and take out the $this->response->header('Content-Length', filesize($image));

References:
https://book.cakephp.org/3.0/en/controllers/request-response.html#sending-files
https://api.cakephp.org/3.3/source-class-Cake.Network.Response.html#1436-1513
http://php.net/manual/en/function.readfile.php