Laravel 13.27 se publicó el 26 de agosto de 2026 con una mezcla de endurecimiento de seguridad y nuevas API del query builder.
El cambio principal es mask_bindings_in_exception_messages, una clave de configuración por conexión. QueryException interpola normalmente los bindings en su mensaje, así que un insert fallido coloca valores como direcciones de correo en getMessage(), que luego terminan en la tabla failed_jobs, archivos de log y spans de APM. Con la opción activada, el mensaje conserva los marcadores ? mientras getBindings() sigue devolviendo los valores. La clave se incluye en el config/database.php del framework, por lo que las aplicaciones que nunca publicaron ese archivo pueden activarla con DB_MASK_BINDINGS=true. El valor por defecto es false. Aportado por @LauJosefsen en el PR #61326.
Los nuevos métodos whereBinary(), orWhereBinary(), whereNotBinary() y orWhereNotBinary() traen comparaciones exactas a nivel de byte al query builder. Las colaciones por defecto de MySQL comparan sin distinguir mayúsculas, así que where('name', 'John') también coincide con john; antes hacía falta whereRaw('name = BINARY ?', ...). MariaDB hereda la gramática de MySQL y también funciona, mientras que Postgres, SQLite y SQL Server lanzan una RuntimeException, igual que whereLike(). Aportado por @xiCO2k en el PR #61261.
refreshForUpdate() recarga un modelo Eloquent en su lugar con lockForUpdate() aplicado. Los modelos suelen resolverse antes de iniciar la transacción, mediante route model binding o el payload de un job, por lo que tomar un bloqueo pesimista implicaba descartar la instancia y volver a consultar por clave primaria. El bloqueo solo dura lo que dura la transacción, así que la llamada pertenece dentro de una, y cierra la condición de carrera entre leer el modelo y escribirlo. Aportado por @stevebauman en el PR #61247.
Una nueva facade Cloud responde a la pregunta "¿estamos en Laravel Cloud?" con tres métodos: Cloud::hosted(), Cloud::usesManagedQueues() y Cloud::queue(). Este último lanza una RuntimeException cuando las colas gestionadas no están configuradas. La facade no se registra deliberadamente en los alias por defecto para evitar colisiones con clases Cloud existentes, y la antigua clase de arranque pasó a llamarse CloudBootstrapper. Aportado por @jackbayliss en el PR #61275.
Las colas ganan Queue::totalPendingSize(), totalDelayedSize() y totalReservedSize(), que suman todas las colas que conoce una conexión sin decodificar los payloads de los jobs. Implementado para los drivers Redis, database, failover y fake (PR #61231).
Las consultas de distancia vectorial ahora funcionan en MariaDB. whereVectorSimilarTo(), whereVectorDistanceLessThan(), orderByVectorDistance() y selectVectorDistance() eran exclusivas de Postgres porque la comprobación era un instanceof PostgresConnection con el operador pgvector <=> escrito directamente. Ambas cosas pasaron a la gramática, y MariaDB 11.7+ compila a vec_distance_cosine(). MySQL puro sigue lanzando excepción, ya que VECTOR_DISTANCE() solo existe en MySQL HeatWave (PR #61250).
El manejo de entradas y la validación recibieron varios endurecimientos de @KIKOmanasijev. Request::merge(['*' => 226]) antes vaciaba todo el array de entrada porque las claves pasaban por data_set(), que trata * como comodín; Uri::withQuery() tenía el mismo fallo. Ambos usan ahora Arr::set() (#61309, #61312). El rechazo de campos desconocidos aplanaba la entrada con Arr::dot(), así que una clave literal "profile.name" eludía la comprobación sin que ninguna regla la validara; las claves de entrada ahora usan el mismo escape que las claves de reglas (#61313). Las reglas in_array y doesnt_contain comparan ahora de forma estricta, lo que acaba con coincidencias falsas como "1e0" contra "1" (#61319, #61318), y MaintenanceModeBypassCookie::isValid() comprueba is_string() en lugar de isset(), de modo que una cookie manipulada con un array ya no convierte un 503 esperado en un 500 no autenticado (#61314).
Puntos menores: las conexiones Postgres aceptan las opciones DSN keepalives, keepalives_idle, keepalives_interval y keepalives_count, para que los cortafuegos ya no maten silenciosamente las conexiones de workers de larga duración (#61307). SQS puede compartir credenciales AWS en caché entre procesos mediante una opción credentials_cache, activada por defecto en las colas gestionadas de Laravel Cloud (#61321). orWhereKey() y orWhereKeyNot() están de vuelta tras el revert del intento de la 13.26 que rompía subclases de Builder; la nueva versión delega a través de un grupo where anidado (#61242). move() y copy() en discos read-through ahora hacen stream desde el fallback cuando el primario aún no ha promovido el archivo (#61272). Los jobs con debounce ya no dejan atrás su timestamp maxWait (#61281), las closures de restricciones de eager loading vuelven a ser estáticas, rompiendo un ciclo de referencias que mantenía vivos los builders en workers de colas y Octane (#61264), e InteractsWithTestCaseLifecycle::flushState() ofrece un hook documentado para limpiar el estado estático entre tests (#61288).
Comentarios
Aún no hay comentarios — escribe el primero.
Inicia la conversación
Sin cuenta ni contraseña — introduce tu correo y te enviamos un enlace de acceso de un solo uso. ¿Primera vez? Todo se configura automáticamente.
Tu valoración se aplicará automáticamente al iniciar sesión.
Revisa tu bandeja de entrada
Hemos enviado un enlace de acceso a …. Ábrelo en este dispositivo — esta pestaña te conectará automáticamente.
¿No llega nada? Mira en la carpeta de spam — y marca el correo como «No es spam» para que la próxima vez llegue directo.