今日已更新 412 条资讯 | 累计 19972 条内容
关于我们

标签:#laravel

找到 46 篇相关文章

AI 资讯

I shipped a support desk by deleting a dependency

I added a support desk to LaraFoundry this week. The first commit in the slice removed a package instead of adding one. LaraFoundry is a reusable SaaS core for Laravel that I'm extracting in public from an older app of mine. Auth, multi-tenancy, roles, activity log, notifications, billing seam, and now support tickets. The rule for every module is the same: lift the proven idea out of the old code, modernise it, harden it, and make it something you can composer require into a fresh Laravel app without inheriting a pile of assumptions. Tickets is where that rule got interesting, because the old code didn't own its ticket model. It leaned on a third-party ticket library. Why a ticket package is wrong for a reusable core A third-party ticket package is a perfectly reasonable choice when you're building one app. You get tables, a model, a status enum and a UI scaffold for free. It's the wrong choice for a core that other apps install. Pull it into the core and every host app inherits that package's migrations, its table names, its status vocabulary and its idea of what a ticket is. The dependency becomes load-bearing in projects that never asked for it, and the day it lags a Laravel release, every downstream app waits. So I cut it (decision D-4.2-1 in my notes) and wrote the model by hand. The model is about 180 lines. There is no magic. Two tables, a uuid, a status, a couple of scopes. The diff against "depend on the package" was less code in the core, not more, because I only kept the behaviour I actually use. Here's the top of the model, with the extraction notes I leave for future me: /** * A support ticket: the channel between a host user and the platform operator. * * Extracted from the donor App\Models\Ticket, which sat on a third-party * ticket package. That dependency is cut: this is a self-contained model. * Categories and labels are JSON slug arrays driven by config, not pivot * tables. The dead assigned_to column and the donor's invalid-operator * query are

2026-06-08 原文 →
AI 资讯

Typed Eloquent boundaries without building a second ORM

Most Laravel teams do not need to "fix" Eloquent. They need to stop letting raw model state leak too far into code that makes real business decisions. That is the practical version of this debate. Typed objects around Eloquent can be a big improvement, but only when they are used as boundaries . If you push the pattern too far, you end up with a second object model shadowing the first one. At that point you are not improving Laravel. You are building a parallel ORM that adds mapping code, cognitive load, and friction on every change. So the right question is not, "Should we replace Eloquent with typed objects?" The right question is, where does untyped Eloquent stop being cheap? Once you frame it that way, the migration path becomes much clearer. Keep Eloquent where it is good at persistence, hydration, scopes, relationships, and query composition. Introduce typed objects where the shape is messy, the values carry business meaning, or invalid combinations are too easy to represent. That is the version that pays off. The Core Recommendation If you only remember one thing from this article, make it this: add typed boundaries around unstable or meaningful data, not around every model . That usually means one of four cases: a JSON column that multiple parts of the app interpret differently domain values like money, status, addresses, or billing configuration data crossing from Eloquent into services, jobs, or integrations code paths where stringly typed state has already caused confusion or bugs Everything else should be guilty until proven useful. This is where a lot of teams go wrong. They see a good example of typed objects and immediately generalize it into an architecture rule. Then every model gets a FooData , FooView , FooState , FooRecord , and FooMapper . The app becomes more "designed" and less understandable. A Laravel codebase does not get better because it has more classes. It gets better because responsibility becomes clearer . Why Raw Eloquent Starts Hurt

2026-06-08 原文 →
AI 资讯

Building a SaaS engine in public: shipping the billing seam, not billing

I tagged v0.9.0 of LaraFoundry this week: billing. Except the honest headline is that I shipped the billing seam , not billing. The free core now has the whole shape of a subscription system, a payment-gateway contract, a driver manager, a real access gate over subscription columns, and it cannot take a single cent. That is on purpose, and the reason is the most interesting part of the phase. LaraFoundry is a SaaS core I'm extracting in public from a live CRM, one module at a time. The deal I made with myself early on: the core is free and stays free for everything except money. Auth, multi-tenancy, RBAC, the admin console, the activity log, i18n, files: all free. The day a business wants to charge its customers , that is the paid part. So billing could not just be "another module." It had to split cleanly down a line, with the free side carrying real, useful structure and the paid side carrying the parts that actually move money. The donor habit I would not carry Here is what the original CRM did when a company "paid" for its subscription: // TODO: real payment gateway integration // TEMPORARY: every payment is successful, for testing $paymentStatus = 'success' ; That success was hardcoded. There was no Stripe, no Paddle, no gateway at all. "Paying" wrote a row into a company_payments table and flipped the subscription date forward. For a CRM I run myself, with one real user, that was fine: I never needed the real thing, so the placeholder sat there indefinitely. The moment this becomes a reusable core, that placeholder is poison. A success that is always true is worse than no gateway, because it looks like billing works. So the rule for this phase was simple: the fake gateway does not get extracted. Whatever stands in its place has to be honest about the fact that it takes no money. What the seam actually is The free core ships a PaymentGatewayInterface : subscribe, cancel, refund, status, and verify a webhook. It describes only the mechanics of moving money. It d

2026-06-04 原文 →
AI 资讯

My Days at Laravel Live Japan 2026

Japanese version available on note . Hi, I'm chatii @chatii . I recently attended Laravel Live Japan 2026. Here's what inspired me and what I took home from the conference. Profile Organizer of PHP Conference Kagawa Encountered PHP back in the 4.x era Freelancer English level: "Can read reasonably well," "Can write a little," "Can listen a bit," "Cannot speak at all." 5/23 PHP×Tokyo - Laravel Live Japan PRE-PARTY PHP×Tokyo - Laravel Live Japan PRE-PARTY - connpass (English follows Japanese) PHP×Tokyoは、PHPやLaravelが好きなエンジニアのためのインターナショナルなミートアップです。 日英のライブ翻訳付きなので、英語が得意でなくても大丈夫です!言語の壁を越えて、PHP/Laravelについて語り合いましょう! 登壇者も募集中です!登壇を希望する方はこちらからご応募ください。 登壇は日本語・英語どちらでも大丈夫です。 #### タイムテーブル * 13:00 - 13:30 受付 & ネットワーキング * 13:30 - 13:40 オープニング * 13:40 - 14:10 "Man... phpxtky.connpass.com I first participated in "PHP×Tokyo March 2026." It was my first time attending a meetup with international participants. I couldn't speak English, but I hoped to be able to communicate somehow. Back in March, David helped me immensely with translation, which made me feel a bit apologetic... At the PRE-PARTY, I took the plunge. During the networking session, I managed to approach Victor Ukam , who gave the talk "Manage AI Prompts as Versioned Files in PHP," and said in English, "I have a question...!" Well... communication after that relied on Google Translate, but I was able to overcome the "first hurdle." You could say I successfully executed <?= "Hello, World" ?> . Also, it was great to see Ivan again, who came from Russia. I first met him in March, and I was so happy he came over to say hello! 5/25 Eve of the Conference, Gyoza Restaurant Zumi organized an unofficial pre-party via the laravel-live-jp channel on the "Laravel Japan" Discord. Participating in these "fringe events" around a conference is always fun. I had booked a hotel from the day before, so I joined in. The real-time translation app that Albert Chen built was incredibly high-performance... 5/26 Day 1 ...Actually, I couldn't sleep at

2026-06-02 原文 →
AI 资讯

How I Fixed a PHP Version Mismatch on Hostinger Shared Hosting (And What Actually Made It Work)

I spent way too long staring at this error. If you're here, you probably are too. Your requirements could not be resolved to an installable set of packages. Problem 1 - Root composer.json requires php ^8.3 but your php version (8.2.30) does not satisfy that requirement. My Laravel 13 app needed PHP 8.3. My Hostinger server was running 8.2. composer install refused to budge. Here's exactly what happened and the one-liner that fixed it. The Setup I was deploying a Laravel 13 + Inertia + React app to Hostinger shared hosting. Laravel 13 requires PHP 8.3 minimum — and so do its locked Symfony 8.x and PHPUnit 12.x dependencies. My composer.lock had been generated on a local machine with PHP 8.3, but Hostinger's CLI was defaulting to 8.2. The hPanel showed PHP 8.3 selected under PHP Configuration . The website itself was running fine on 8.3. But SSH? Still on 8.2. $ php -v PHP 8.2.30 ( cli ) That disconnect — hPanel vs. CLI — is the trap. What I Tried First composer update My first instinct was to just let Composer resolve newer compatible versions: composer update No luck. The root composer.json itself declared "php": "^8.3" , so Composer refused before even touching the lock file. The PHP constraint wasn't just in dependencies — it was in my own project requirements. composer install --ignore-platform-reqs This flag skips platform checks and forces the install anyway. It works , but it's a lie — you end up with packages that may behave incorrectly or fail at runtime because they genuinely require PHP 8.3 features. Not a real fix. Changing PHP in hPanel Hostinger's control panel has a PHP version switcher under Hosting → Manage → PHP Configuration . I had already set this to 8.3. This controls the web server / FPM version — what runs your .php files in the browser. It does not change what php points to in your SSH terminal. That's the key distinction most tutorials miss. What Actually Fixed It Hostinger installs multiple PHP versions in parallel. They live in /opt/alt/ph

2026-06-01 原文 →
AI 资讯

Adding a full docker setup to the Filament Mastery Starters

For a while, my starter kits didn't include any Docker configuration. The foundation was solid with auth, roles, MFA, Horizon, Logs Viewer, but the deployment side was left to whoever cloned the project. That was a deliberate choice at first. Docker setups vary a lot depending on the infrastructure: some people use a reverse proxy, others have Cloudflare in front, some run on bare metal, others on managed platforms. I didn't want to ship something that would need to be ripped out immediately. But over time I changed my mind. Here's why and what the process taught me. The problem with "just configure it yourself" Leaving deployment out of a starter kit sounds reasonable. In practice, it means every project starts with the same 4-6 hours of Docker work that never really changes. Multi-stage Dockerfile. PHP-FPM config. Nginx with HTTPS. PostgreSQL and Redis wired up. Horizon and the scheduler running as proper services. Healthchecks everywhere so Docker knows when things are actually ready. None of it is so complicated. But it's time-consuming, easy to get subtly wrong, and almost identical from one project to the next. Once I admitted that, the question wasn't whether to include Docker, it was how to do it in a way that's actually useful without being too opinionated about production infrastructure. What I ended up building The setup I settled on covers the full local development stack: A multi-stage Dockerfile : separate stages for Composer dependencies, Node assets, and the final PHP-FPM image. Keeps the production image lean. Nginx with HTTP-to-HTTPS redirect and a self-signed certificate for local dev, already included, no setup needed. PostgreSQL and Redis as services with proper healthchecks. Horizon and the scheduler as dedicated services, not crammed into the main app container. A bootstrap service that runs php artisan migrate --force before the app starts. The Dockerfile uses three stages to keep the final image as lean as possible: FROM php:8.4-fpm-alpine A

2026-05-29 原文 →