PHP Reddit – Telegram
PHP Reddit
34 subscribers
294 photos
39 videos
25K links
Channel to sync with /r/PHP /r/Laravel /r/Symfony. Powered by awesome @r_channels and @reddit2telegram
Download Telegram
Announcing Kreuzberg v4

Hi Peeps,

I'm excited to announce Kreuzberg v4.0.0.

## What is Kreuzberg:

Kreuzberg is a document intelligence library that extracts structured data from 56+ formats, including PDFs, Office docs, HTML, emails, images and many more. Built for RAG/LLM pipelines with OCR, semantic chunking, embeddings, and metadata extraction.

The new v4 is a ground-up rewrite in Rust with a bindings for 9 other languages!

## What changed:

- Rust core: Significantly faster extraction and lower memory usage. No more Python GIL bottlenecks.
- Pandoc is gone: Native Rust parsers for all formats. One less system dependency to manage.
- 10 language bindings: Python, TypeScript/Node.js, Java, Go, C#, Ruby, PHP, Elixir, Rust, and WASM for browsers. Same API, same behavior, pick your stack.
- Plugin system: Register custom document extractors, swap OCR backends (Tesseract, EasyOCR, PaddleOCR), add post-processors for cleaning/normalization, and hook in validators for content verification.
- Production-ready: REST API, MCP server, Docker images, async-first throughout.
- ML pipeline features: ONNX embeddings on CPU (requires ONNX Runtime 1.22.x), streaming parsers for large docs, batch processing, byte-accurate offsets for chunking.

## Why polyglot matters:

Document processing shouldn't force your language choice. Your Python ML pipeline, Go microservice, and TypeScript frontend can all use the same extraction engine with identical results. The Rust core is the single source of truth; bindings are thin wrappers that expose idiomatic APIs for each language.

## Why the Rust rewrite:

The Python implementation hit a ceiling, and it also prevented us from offering the library in other languages. Rust gives us predictable performance, lower memory, and a clean path to multi-language support through FFI.

## Is Kreuzberg Open-Source?:

Yes! Kreuzberg is MIT-licensed and will stay that way.

## Links

- Star us on GitHub
- Read the Docs
- Join our Discord Server


https://redd.it/1q9stan
@r_php
Generating PDF contracts in Laravel: DomPDF vs Spatie/Browsershot?

I’m building a small app in Laravel to generate and sign contracts.
For the PDF version of those contracts I’ve always used barryvdh/laravel-dompdf and it’s been “good enough”.
Lately I’m seeing more people using Spatie’s Browsershot / laravel-pdf for PDFs.

For a contracts use case (multi-page, decent layout, mostly text with some branding), would you stick to DomPDF or move to Browsershot?
Any real-world pros/cons in terms of CSS support, performance or server setup that I should consider?

https://redd.it/1qa6hgh
@r_php
CKEditor 5 Symfony Integration
https://redd.it/1qanbko
@r_php
Why is something like PHP-FPM necessary in PHP, but not in other languages such as JS (nodejs) or Go lang?

I want to deploy my PHP website on my VPS and thought it would be simpler. I use NGINX as a reverse proxy, and if I want to connect it to PHP, it seems I need something like PHP-FPM, which has several configurations that overwhelm me.



I saw that PHP has a built-in server, but apparently it's only for development and is not recommended for production use. In other environments such as NodeJS or Golang, I don't see the need for another tool like php-fpm. Am I missing something? Maybe there's a simpler way without all the configuration hassle?

https://redd.it/1qagk8i
@r_php
A slightly faster language server for php-cs-fixer

https://github.com/balthild/php-cs-fixer-lsp

It starts php-cs-fixer runners and keep them running in the background. This makes formatOnSave less laggy.

https://redd.it/1qb97qn
@r_php
How do you track temporary workarounds in Laravel projects?

In large Laravel applications, temporary workarounds often turn into permanent technical debt if they aren’t tracked carefully.

One approach is to **mark workarounds with a denoscription and an expiration date using PHP attributes**. With this system, teams can:

* List all workarounds and their current status (healthy or expired)
* Fail CI/CD builds when a workaround has expired
* Provide local feedback when expired code is executed (only in local environments)

Controller classes and methods can be automatically discovered, while other classes (services, jobs, listeners, etc.) can be explicitly enforced where needed.

This strategy helps teams enforce accountability and catch forgotten workarounds before they become problems.

For anyone interested, there’s an open-source implementation here: [https://github.com/medmahmoudhdaya/laravel-deadlock](https://github.com/medmahmoudhdaya/laravel-deadlock)

https://redd.it/1qauky3
@r_php
Weekly help thread

Hey there!

This subreddit isn't meant for help threads, though there's one exception to the rule: in this thread you can ask anything you want PHP related, someone will probably be able to help you out!

https://redd.it/1qao5uz
@r_php
You can add arguments/options to any artisan CLI commands, even if they aren't yours

Our use case: Our permission system is very strict, and if no user is logged in (web) or tied to a job (queue) then permission checks are rejected.

But this interfers with tinker, which we use on the CLI (the web version is not affected, since we are logged in) and we didn't want to disable permissions for the whole CLI.

Solution: two simple listeners to add CLI arguments/options to any artisan commands:

<?php

namespace App\Listeners;

use Illuminate\Console\Events\ArtisanStarting;
use Symfony\Component\Console\Input\InputOption;

class AddPermissionsFlagsToConsoleCommand
{
    public function handle(ArtisanStarting $event): void
    {
        $definition = $event->artisan->getDefinition();
        $definition->addOption(new InputOption('--disable-permissions', null, InputOption::VALUE_NONE, 'Disable all permissions check'));

        $event->artisan->setDefinition($definition);
    }
}

<?php

namespace App\Listeners;

use App\Features\Permissions\Permissions;
use Exception;
use Illuminate\Console\Events\CommandStarting;

class ResolvePermissionsForConsoleCommand
{
    const DISALLOWED_COMMANDS = [
        'about',
    ];

    const REQUIRED_COMMANDS = [
    ];

    public function handle(CommandStarting $event): void
    {
        $disablePermissions = $event->input->getOption('disable-permissions');

        if (! $disablePermissions) {
            return;
        }

        if (\in_array($event->command, self::DISALLOWED_COMMANDS)) {
            throw new Exception('You cannot specify --disable-permissions for this command');
        }

        if (\in_array($event->command, self::REQUIRED_COMMANDS)) {
            throw new Exception('You must specify --disable-permissions to run this command');
        }

// YOUR OWN LOGIC HERE

        Permissions::bypassPermissions(true);
    }
}

https://redd.it/1qbu7tp
@r_php