IronWoods.es

Desarrollo web

¿Qué es Tinker?

Tinker es una herramienta en línea de comandos para hacer pruebas rápidas de PHP / Laravel, disponible desde Laravel 5.4.


Tinker permite probar a la mayoría de las funciones disponibles en PHP y Laravel, sin tener que alterar el código ni indicar los namespaces, así si tenemos un modelo en "App\Models\Pruebas" llamado Foo, podemos hacer una consulta simplemente llamando a Foo, sin indicar el namespace.

Trazas en el código vs uso de Tinker

Para ver el resultado de una consulta a la BD podríamos imprimir el resultado con dd() o dump() en el código que estamos desarrollando o en una sesión de Laravel Tinker.

Tinker es cómodo y rápido, su desventaja principal es una menor legibilidad en ciertos resultados que la que obtendremos al imprimir las trazas en el navegador, por ejemplo, al obtener una colección con Eloquent, verlo en consola es notablemente menos legible.

A su favor, Tinker nos evita modificar el código y tener que refrescar el navegador, lo que puede a veces incluso alterar el estado de nuestra base de datos.

Uso de Tinker

Para usar Tinker, primero debe estar instalado. La forma más sencilla de hacerlo es mediante el comando:

composer require laravel/tinker


Para iniciar Tinker (iniciar sesión de Tinker) abrir la terminal y usar el comando:

php artisan tinker


y para salir:

exit

Podemos ver el resultado de escribir código PHP

echo 'Hola mundo' . PHP_EOL;


Se muestra: Hola mundo

Podemos ver el resultado de consultas Eloquent

dump(User::all());


o aún mejor, simplemente con:

User::all()


Así, podremos consultar ciertos datos o simplemente probar si nuestras consultas funcionan, por ejemplo:

User::where('role', 'admin')->get(['id', 'created_at'])->first()


devuelve:

App\Models\User {#3051

id: 1,

created_at: "2019-08-25 00:00:00",

}

Nota: si usamos el método dd() se cierra la sesión de Tinker.

Prueba con fechas y Carbon

$created_at = App\Models\User::find(1)->created_at;

\Carbon\Carbon::parse($created_at, 'Europe/Madrid')->format('d-m-Y, H:i:s');

\Carbon\Carbon::parse($created_at, 'Europe/Madrid')->isoFormat('DD-MM-YYYY, HH:mm:ss');


Fichero SQL - Volcado de la BD para las pruebas.

Plus: trazando el SQL en consultas Eloquent

Resulta que si ejecutamos una consulta Eloquent y la BD no está accesible (no arrancamos los servicios Apache / MySql por ejemplo), aparecerá un error SQLSTATE seguido de la consulta SQL completa.

Ejemplo: tratamos de obtener el primer usuario.

User::first();


Resultado:

[!] Aliasing 'User' to 'App\Models\User' for this Tinker session.

Illuminate/Database/QueryException with message 'SQLSTATE[HY000] [2002]...

(SQL: select * from `users` limit 1)


Y esto puede ser muy útil cuando estamos montando consultas complejas... Pero hay, quizá, opciones más flexibles que provocar el error (que fue como me imagine que existían):

1. Usar el método toSql().

2. Usar el query log de Eloquent (bueno, este ya lo había usado en el código).

3. Escuchar y volcar las consultas a la BD.


Uso de toSql()

Este método sustituye a ->all(), ->get(), ->first(), ... en su caso. Podemos perder el final de ciertas consultas, como ... LIMIT 1 (tendríamos que forzarlo con take(1)) y no aparecerán los parámetros, pero es el más cómodo de usar.


Ejemplos con toSql()

Nota: voy a indicar la consulta seguida del resultado para acortar...

User::first()->toSql()

"select * from `users`"

User::take(1)->toSql()

"select * from `users` limit 1"

User::whereNull('deleted_at')->where('name', 'xxx')->toSql()

"select * from `users` where `deleted_at` is null and `name` = ? and `users`.`deleted_at` is null"


Uso de query log

Este método muestra más información que el anterior, como los parámetros pasados o el tiempo de ejecución de la consulta. Para usarlo lo activamos con el comando:

DB::enableQueryLog()


Y volcamos el resultado después de la consulta con:

DB::getQueryLog()


Ejemplo con query log

>>> DB::enableQueryLog()

=> null

>>> User::whereNull('deleted_at')->where('name', 'xxx')->first()

[!] Aliasing 'User' to 'App\Models\User' for this Tinker session.

=> null

>>> DB::getQueryLog()

=> [

[

"query" => "select * from `users` where `deleted_at` is null and `name` = ? and `users`.`deleted_at` is null limit 1",

"bindings" => [

"xxx",

],

"time" => 19.0,

],

]

>>>


En cuanto al último método, que es similar a query log, se puede escribir lo siguiente al principio de la sesión de Tinker para que imprima la información pertinente, por ejemplo, la consulta:

User::get(['name', 'profession', 'gender'])


si previamente hemos escrito el comando de escucha y colcado los datos:

DB::listen(function ($query) {

dump($query->sql);

dump($query->bindings);

dump($query->time);

});


da como resultado:

"select `name`, `profession`, `gender` from `users`"

[]

1.0

=> Illuminate\Database\Eloquent\Collection {#2986

all: [

App\User {#2980

name: "foo",

profession: "web admin",

gender: "other",

},

App\User {#2983

name: "baz",

profession: "developer",

gender: null,

},

],

}