Injecting controller actions in Laravel views

Disclaimer: Depending on the kind of logic you need, it’s also possible to use View Composers to achieve a similar result.

I’m using Laravel in this new project I’m working on. Some other PHP frameworks have a feature to use controllers as services. Symfony, for instance, has something like that. The project team thought Laravel, as Symfony-based, would have something like that. Well, if it has, it’s not clear in the docs.

Another team member ended up with a solution I never thought before:

 @inject('someController', 'App\Http\Controllers\SomeController')
 {!! $someController->index() !!}

Now, we’re using Blade’s @inject directive to call controller actions from inside views. That’s useful for reusing actions as widgets, for example.

If you find that interesting and want to use in your application, remember two things:

  1. Since you’re calling the action method directly, you have to pass all the required params. If it expects a request instance, you can do this: $someController->index(request()).
  2. Probably the method returns a view that contains HTML code. So wrap the call within {!! and !!}. Using the {{ }} regular tag will cause the code to be escaped.

Debugging requests with cURL

For more than one time I had to debug HTTP request or response headers and other details. To do that, I use two techniques, both based on cURL library. I explain them ahead.

Technique #1: From the command line

This is the easiest way to debug. It doesn’t require writing any actual code. Just call curl program from the command line, as usual, adding a new param: -vvv. This will enable the highest verbosity level.

$ curl -vvv http://google.com
* Rebuilt URL to: http://google.com/
* Trying 2800:3f0:4001:802::200e...
* Connected to google.com (2800:3f0:4001:802::200e) port 80 (#0)
> GET / HTTP/1.1
> Host: google.com
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 302 Found
< Cache-Control: private
< Content-Type: text/html; charset=UTF-8
< Location: http://www.google.com.br/?gfe_rd=cr&ei=bUG8V53JGcvK8gfp3L-YBg
< Content-Length: 262
< Date: Tue, 23 Aug 2016 12:28:29 GMT
< 
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.com.br/?gfe_rd=cr&amp;ei=bUG8V53JGcvK8gfp3L-YBg">here</A>.
</BODY></HTML>
* Connection #0 to host google.com left intact

As you can see in the example above, it outputs all request and response info.

It’s possible to output everything to a file, by adding > output_file.txt to the end of the command. Using our previous call:

$ curl -vvv http://google.com > output.txt

Well, one may now ask: if this is so easy, why do you have a second way to debug request? Following we’ll see why that.

Technique #2: From a PHP script

I’ve written on debugging cURL and PHP at Kettle.io Blog. Let’s say you have to send a dynamic header with the request, like a JWT authorization token. It’s not impossible to that from the command line, but it’s easier using programming. For those cases, I use the cURL PHP extension. Check out the script below.

$url = 'http://google.com';
$headers = [
    'Accept' => 'application/json',
];

/*
 * We're going to use the output buffer to store the debug info.
 */
ob_start();
$out = fopen('php://output', 'w');

$handler = curl_init($url);

/*
 * Here we set the library verbosity and redirect the error output to the 
 * output buffer.
 */
curl_setopt($handler, CURLOPT_VERBOSE, true);
curl_setopt($handler, CURLOPT_STDERR, $out);

$requestHeaders = [];
foreach ($headers as $k => $v) {
    $requestHeaders[] = $k . ': ' . $v;
}
curl_setopt($handler, CURLOPT_HTTPHEADER, $requestHeaders);
curl_setopt($handler, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($handler);
fclose($out);

/*
 * Joining debug info and response body.
 */
$data = ob_get_clean();
$data .= PHP_EOL . $response . PHP_EOL;
echo $data;

Now, you can customize this code to add some dynamic data to a header or any other request part. After doing that, run it using the PHP program from the command line:

$ php curldebug.php

P.S.: I’m assuming that you saved the script as curldebug.php.

As we did with the curl program, it’s possible to output everything to a file. Just append the > output_file.txt to the call.

Conclusion

Debugging requests can be a lifesaver when dealing with third-party APIs and other services. Headers may contain helpful info to find what is going wrong with that weird response body.

Propel + Symfony2 : Debugando queries em comandos

Quando no ambiente de desenvolvimento, em um projeto baseado no Symfony2, usar o webprofiler na interface web (a partir da barra que fica no rodapé das páginas) é uma mão na roda em várias situações. Mas no console geralmente não temos essa facilidade tão a mão, porém não é impossível acessá-la. Especificamente para as queries executadas através do Propel, é possível usar o seguinte trecho para fins de debug:

$profiler = $this->getContainer()->get('profiler');
$db = $profiler->get('propel');
$db->collect(new \Symfony\Component\HttpFoundation\Request(), new \Symfony\Component\HttpFoundation\Response()); // Stubs, não são usados pelo profiler
var_dump($db->getQueries());

Você pode dar uma olhada na classe Symfony\Bridge\Propel1\DataCollector\PropelDataCollector e conferir os métodos disponíveis.

Outros profilers podem ser acessados através do container, mas como a requisição (request) e a resposta (response) não estão disponíveis no console, pode ser que nem todos funcionem como esperado.