Laravel 13.27 erschien am 26. August 2026 mit einer Mischung aus sicherheitsrelevanten Härtungen und neuen Query-Builder-APIs.
Die wichtigste Neuerung ist mask_bindings_in_exception_messages, ein Konfigurationsschlüssel pro Datenbankverbindung. QueryException interpoliert Bindings normalerweise in die Fehlermeldung, sodass ein fehlschlagender Insert Werte wie E-Mail-Adressen in getMessage() schreibt, die dann in der failed_jobs-Tabelle, in Logdateien und APM-Spans landen. Ist die Option aktiv, bleiben die ?-Platzhalter erhalten, während getBindings() weiterhin die Werte liefert. Der Schlüssel steckt in der mitgelieferten config/database.php, sodass Anwendungen ohne publizierte Konfiguration ihn mit DB_MASK_BINDINGS=true aktivieren können. Standard ist false. Beigetragen von @LauJosefsen in PR #61326.
Die neuen Methoden whereBinary(), orWhereBinary(), whereNotBinary() und orWhereNotBinary() bringen bytegenaue Vergleiche in den Query Builder. MySQLs Standard-Collations vergleichen ohne Berücksichtigung der Groß- und Kleinschreibung, where('name', 'John') trifft also auch john; bisher war dafür whereRaw('name = BINARY ?', ...) nötig. MariaDB erbt die MySQL-Grammatik und funktioniert ebenfalls, Postgres, SQLite und SQL Server werfen eine RuntimeException, analog zu whereLike(). Beigetragen von @xiCO2k in PR #61261.
refreshForUpdate() lädt ein Eloquent-Modell mit lockForUpdate() an Ort und Stelle neu. Modelle werden typischerweise vor Transaktionsbeginn aufgelöst, etwa über Route Model Binding oder einen Job-Payload, sodass ein pessimistischer Lock bisher bedeutete, die Instanz zu verwerfen und per Primärschlüssel neu zu laden. Der Lock gilt nur für die Dauer der Transaktion, der Aufruf gehört also in eine solche, und schließt die Race Condition zwischen Lesen und Zurückschreiben. Beigetragen von @stevebauman in PR #61247.
Eine neue Cloud-Facade beantwortet die Frage "laufen wir auf Laravel Cloud?" mit drei Methoden: Cloud::hosted(), Cloud::usesManagedQueues() und Cloud::queue(). Letztere wirft eine RuntimeException, wenn keine verwalteten Queues konfiguriert sind. Die Facade wird bewusst nicht in den Standard-Aliases registriert, um Kollisionen mit vorhandenen Cloud-Klassen zu vermeiden; die bisherige Bootstrap-Klasse heißt nun CloudBootstrapper. Beigetragen von @jackbayliss in PR #61275.
Queues erhielten Queue::totalPendingSize(), totalDelayedSize() und totalReservedSize(), die über alle Queues einer Verbindung summieren, ohne Job-Payloads zu dekodieren. Implementiert für die Redis-, Datenbank-, Failover- und Fake-Treiber (PR #61231).
Vektor-Distanz-Abfragen funktionieren jetzt unter MariaDB. whereVectorSimilarTo(), whereVectorDistanceLessThan(), orderByVectorDistance() und selectVectorDistance() waren Postgres-only, weil der Check ein instanceof PostgresConnection war und der pgvector-Operator <=> fest eingebaut war. Beides wanderte in die Grammatik, und MariaDB 11.7+ kompiliert zu vec_distance_cosine(). Reines MySQL wirft weiterhin eine Exception, da VECTOR_DISTANCE() nur auf MySQL HeatWave existiert (PR #61250).
Bei Input-Verarbeitung und Validierung gab es mehrere Härtungen von @KIKOmanasijev. Request::merge(['*' => 226]) leerte bislang das gesamte Input-Array, weil Schlüssel über data_set() liefen, das * als Wildcard behandelt; Uri::withQuery() hatte denselben Fehler. Beide nutzen jetzt Arr::set() (#61309, #61312). Die Ablehnung unbekannter Felder flachte Input mit Arr::dot() ab, sodass ein literaler "profile.name"-Schlüssel die Prüfung umging, während keine Regel ihn validierte; Input-Schlüssel werden nun mit derselben Escaping-Logik wie Regel-Schlüssel abgeglichen (#61313). Die Regeln in_array und doesnt_contain vergleichen nun strikt, wodurch falsche Treffer wie "1e0" gegen "1" der Vergangenheit angehören (#61319, #61318), und MaintenanceModeBypassCookie::isValid() prüft is_string() statt isset(), sodass ein präparierter Array-Cookie einen erwarteten 503 nicht mehr in einen nicht authentifizierten 500 verwandelt (#61314).
Kleinere Punkte: Postgres-Verbindungen akzeptieren die DSN-Optionen keepalives, keepalives_idle, keepalives_interval und keepalives_count, damit Firewall-Idle-Timeouts langlebige Worker-Verbindungen nicht mehr still beenden (#61307). SQS kann gecachte AWS-Credentials über eine credentials_cache-Option prozessübergreifend teilen; Laravel Cloud aktiviert sie für Managed Queues standardmäßig (#61321). orWhereKey() und orWhereKeyNot() sind zurück, nachdem der Versuch in 13.26 wegen gebrochener Builder-Subklassen revertiert wurde; die neue Version delegiert über eine verschachtelte Where-Gruppe (#61242). move() und copy() auf Read-Through-Disks streamen nun vom Fallback, wenn der Primary die Datei noch nicht promoviert hat (#61272). Debounced Jobs hinterlassen ihren maxWait-Zeitstempel nicht mehr (#61281), Eager-Load-Constraint-Closures sind wieder statisch und durchbrechen einen Referenzzyklus, der Builder in Queue-Workern und Octane am Leben hielt (#61264), und InteractsWithTestCaseLifecycle::flushState() bietet einen dokumentierten Hook zum Aufräumen statischen Zustands zwischen Tests (#61288).
Kommentare
Noch keine Kommentare — schreib den ersten.
Starte die Diskussion
Kein Konto, kein Passwort nötig — gib einfach deine E-Mail-Adresse ein, wir senden dir einen einmaligen Anmelde-Link. Beim ersten Mal bist du damit automatisch angemeldet.
Deine Bewertung wird nach der Anmeldung automatisch übernommen.
Schau in dein Postfach
Wir haben einen Anmelde-Link an … gesendet. Öffne ihn auf diesem Gerät — dieser Tab meldet dich automatisch an.
Nichts angekommen? Wirf einen Blick in den Spam-Ordner — und markiere die Mail dort als „Kein Spam“, dann landet sie künftig direkt im Postfach.