We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Getting Returned value from $app->mount() controller

Here is the deal.

$app->before(function () use ($app) {   
    $app->response->setHeader("Content-Type", "application/json"); 
  return true;
});

$app->after(function() use ($app){

    // This will work for strings. but any array or objects will get a conversion error.
    // Also i ahve to set it like this in the controller. $this->response->setContent($stuff);
    // I woudl rather return it to the app handler like this return($stuff);
    // controller is below
    $app->response->getContent();

    // the app object here has a return value that is protected. is their a function
    // call to retrieve this data? 
    // below is the var dump of $app in the after call. How can i access this return value? 
    // so i can add it into the respons via $app->response->setJsonContent($return);

     [_returnedValue:protected] => Array
     (
       [0] => test
       [1] => this
       [stuff] => Array
       (
         [0] => really
         [1] => good
       )
     )

    $app->response->setJsonContent($app->response->getContent())->send();
});

$test = new Phalcon\Mvc\Micro\Collection();
$test->setHandler('Api\Controllers\TestController', true);
$test->get('/','index');
$app->mount($test);

Controller


<?php
namespace Api\Controllers;

use Phalcon\Mvc\Controller;

class TestController extends Controller
{

    public function index()
    {
        $array = ['test','this','stuff' => ['really','good']];

        // this works but then i have to json encode before i set or i get a string conversion error. 
        // which then kind of negates the re
        $this->response->setContent($array);

        // this woudl be my prefered method, but i can't seem to get at the object back in the $app->after()
        return $array;
    }
}
edited Jun '16

I found a solution but i am not crazy about it just because of the extra code in every controller response.

// TestController.php
  public funciton index()
  {
      //...
      $this->response->setJsonContent($array);
  }

// app.php

$app->after(function() use ($app){
    $app->response->send();
});

while this is working... I think something like this code is a lot cleaner if i could get the return value.

// TestController.php
public funciton index()
{
    //...
    return $array;
}

// app.php

$app->after(function() use ($app){
    // this is a little messier here but the returns in the controllers are cleaner and hard to mess up...
    $app->response->setJsonContent( $app->returnValue );
    $app->response->send();
});


85.5k

i myself have a module for ajax requests, where i have


  public function afterExecuteRoute(\Phalcon\Mvc\Dispatcher $dispatcher) {

    $this->response->setContentType('application/json', 'UTF-8');

  }


79.0k
Accepted
answer
edited Jun '16

it is always better to handle response in one code block. In Micro apps, echo or print should be avoided.

This is how I handle it.

//Executed after the handler is executed. It can be used to prepare the response
$app->after(function () use ($app) {
    // This is executed after the route is executed

    //prepare HTTP response headers
        $app->response->setCache(0); //disable cache
        $app->response->setHeader('Cache-Control', 'private, max-age=0, must-revalidate'); //disable cache
        $app->response->setHeader('X-SAPI', php_sapi_name());  //Just for fun, add SAPI HTTP header
        $app->response->setHeader('X-Runtime', zend_version()); //Just for fun, add Zend Engine version HTTP field
        $app->response->setHeader('X-Version', \Phalcon\Version::get()); //Just for fun, add framework version

    //set HTTP body
        $app->response->setContentType('application/json'); //set content type
        is_array($app->getReturnedValue()) ?  //Inject common response index
            $app->response->setJsonContent([Constantia::API_RETURN_ROOT_KEY => $app->getReturnedValue()], JSON_NUMERIC_CHECK) :
            $app->response->setJsonContent([Constantia::API_RETURN_ROOT_KEY => 'GENERAL ERROR', 'Code' => 0xff], JSON_NUMERIC_CHECK);

    //THIS IS MANDATORY IN ORDER TO TELL NGINX WHENEVER TO TAKE INTO ACCOUNT GZIP MIN LIMIT!
        $app->response->setHeader('Content-Length', strlen($app->response->getContent())); //Calculate Content-Length header

    //update audit log record
        $app->db->execute('UPDATE Audit SET response_content = ? WHERE AuditID = ?', [$app->response->getContent(), $app->persistent->auditID]);
});

That is prepared response, but the actual output is done via:

//Executed after sending the response. It can be used to perform clean-up
$app->finish(function () use ($app){
    // This is executed when the request has been served by the route handler and response has been returned

//Finally, send the prepared response, flush output buffers (HTTP header)
    !$app->response->isSent() && $app->response->send();

    //Stops the middleware execution avoiding than other middleware be executed
    $app->stop();
});

Last but not least, index.php must not echo the handle method:

    /**
     * Handle the request
     */
    $app->handle();