shahriar_shaon's avatar

shahriar_shaon wrote a reply+100 XP

3mos ago

It will work, but it’s not safe or recommended.

Invalidating or regenerating a session changes the application state, and GET requests should be read-only. GET routes are not CSRF-protected and can be triggered unintentionally (by browsers, bots, or malicious sites).

Use a POST route with CSRF protection for logout or session regeneration instead.

Route::post('/logout', function (Request $request) {
	Auth::logout();

    $request->session()->invalidate();
    $request->session()->regenerateToken();

    return response()->json(['message' => 'Logged out']);
});
shahriar_shaon's avatar

shahriar_shaon wrote a reply+100 XP

4mos ago

I actually gave the GitHub link first, but I wasn't getting a good response, so I'll post another one with the direct code.

shahriar_shaon's avatar

shahriar_shaon was awarded Best Answer+1000 XP

4mos ago

You don't have to run this command by hand on your production server: php artisan queue:work. Since you're using Forge, the best way is to set up a Queue Worker (Daemon) so it runs in the background and restarts automatically.

Here’s what you should do on Forge:

  1. Go to your Server → select your Site.
  2. Open the Workers (or Daemons) tab.
  3. Create a new worker with a command like:
php artisan queue:work --tries=3 --timeout=120
  1. Forge will keep this worker running permanently, restart it if it crashes, and start it again after a reboot
  2. Make sure your .env queue driver is set properly (e.g., QUEUE_CONNECTION=database or redis).

This is the recommended way of running queue workers in production. If you'd like, you can also run Horizon instead of queue:work.

shahriar_shaon's avatar

shahriar_shaon wrote a reply+100 XP

4mos ago

I'm confused about my code structure. Am I on the right track?

I need to know more. When I use PHPStan Max Level, do I have to use annotations in this way?


public function store(StoreUserRequest $request, CreateUser $action): RedirectResponse
    {
        Gate::authorize('create', User::class);

        /** @var array{name: string, email: string, phone: string, is_active: string, password: string|null, avatar: UploadedFile|null, avatar_removed: bool, roles: array<int>, permissions: array<int>} $data */
        $data = $request->validated();
shahriar_shaon's avatar

shahriar_shaon wrote a reply+100 XP

4mos ago

You don't have to run this command by hand on your production server: php artisan queue:work. Since you're using Forge, the best way is to set up a Queue Worker (Daemon) so it runs in the background and restarts automatically.

Here’s what you should do on Forge:

  1. Go to your Server → select your Site.
  2. Open the Workers (or Daemons) tab.
  3. Create a new worker with a command like:
php artisan queue:work --tries=3 --timeout=120
  1. Forge will keep this worker running permanently, restart it if it crashes, and start it again after a reboot
  2. Make sure your .env queue driver is set properly (e.g., QUEUE_CONNECTION=database or redis).

This is the recommended way of running queue workers in production. If you'd like, you can also run Horizon instead of queue:work.

shahriar_shaon's avatar

shahriar_shaon wrote a reply+100 XP

4mos ago

I did that, but it didn't work.

shahriar_shaon's avatar

shahriar_shaon liked a comment+100 XP

4mos ago

with this maybe?:

 /** @var AccountTypeData $data */
    $data = $request->validated();
shahriar_shaon's avatar

shahriar_shaon wrote a reply+100 XP

4mos ago

Thank you so much

shahriar_shaon's avatar

shahriar_shaon liked a comment+100 XP

4mos ago

See Nuno and Brent's opinion of Level 9 here https://youtu.be/QFh21mFLH8I?si=gIQOuHwnJDUX0-UR

shahriar_shaon's avatar

shahriar_shaon wrote a reply+100 XP

4mos ago

Yes, thank you so much, it's work

I want to know how I can handle that section

public function store(StoreAccountTypeRequest $request, CreateType $action): RedirectResponse
    {
        Gate::authorize('create', AccountType::class);

        /** @var array{code: string, name: string, normal_balance_debit: bool, is_active: string, description: string|null} $data */
        $data = $request->validated();

You see, I have to write a lot of heavy annotations just to satisfy PHPStan. cause FormRequest returns me mixed value

shahriar_shaon's avatar

shahriar_shaon wrote a reply+100 XP

4mos ago

I actually ran into the same problem recently on a shared hosting environment. Even though my database credentials were correct, the connection kept failing.

What I learned is that on shared hosting, DB_HOST=127.0.0.1 usually doesn’t work. In most cases, you have to use

DB_HOST=localhost

Some providers even give you a custom hostname, something like:

DB_HOST=mysql.yourdomain.com

You can find the correct value in cPanel under MySQL Databases -> Hostname.

Another thing to watch out for is the MySQL port. Some hosts use a different port (like 3307), and if the port doesn’t match, you’ll still get the same “Access denied” error even with the right credentials.

shahriar_shaon's avatar

shahriar_shaon wrote a reply+100 XP

4mos ago

I intentionally use final on classes. If a class is not intended to be extended, marking it as final provides an explicit indicator of that intent. It prevents accidental inheritance, keeps the architecture predictable, and encourages composition over unnecessary subclassing.

It also contributes to ease of codebase maintenance, as those classes cannot have their behavior changed through inheritance, thus avoiding any unexpected side effects in the future.

shahriar_shaon's avatar

shahriar_shaon started a new conversation+100 XP

4mos ago

My confusion: I’m using PHPStan at the maximum level, which means I have to write a lot of heavy annotations just to satisfy PHPStan. Also, I’ve never used DTOs before — this is my first project using them — so I’m not even sure if I’m following the correct approach.

What’s troubling me the most is that after validating the data, when I pass it into the DTO, PHPStan keeps giving warnings because of mixed values.

I’m sharing my project’s GitHub link below. If anyone kind-hearted could take a look at my code, point out where I’m going wrong, and guide me toward the proper way to structure things, I would really appreciate it.

github.com/shahriarshaon1993/myfinance

My DTO: RoleDto.php

Request validation: StoreAccountTypeRequest.php

public function rules(): array
    {
        return [
            'code' => ['required', 'string', 'min:2', 'max:50', 'regex:/^[A-Z_]+$/', 'unique:account_types,code'],
            'name' => ['required', 'string', 'min:2', 'max:50'],
            'description' => ['nullable', 'string', 'min:2', 'max:500'],
            'normal_balance_debit' => ['required', 'boolean'],
            'is_active' => [Rule::enum(ActiveStatus::class)],
        ];
    }

    /**
     * @return string[]
     */
    public function messages(): array
    {
        return [
            'code.regex' => 'The code may only contain uppercase letters and underscores.',
        ];
    }

Controller is: AccountTypeController.php

public function store(StoreAccountTypeRequest $request, CreateType $action): RedirectResponse
    {
        Gate::authorize('create', AccountType::class);

        /** @var array{code: string, name: string, normal_balance_debit: bool, is_active: string, description: string|null} $data */
        $data = $request->validated();

        $action->handle(AccountTypeDto::fromArray($data));

        return to_route('accounting.types.index')
            ->with('success', 'Account type created successfully.');
    }

Store action class: CreateAccountType.php

public function handle(AccountTypeDto $type): AccountType
    {
        return AccountType::create($type->toArray());
    }
shahriar_shaon's avatar

shahriar_shaon liked a comment+100 XP

4mos ago

Appreciate your help :)

shahriar_shaon's avatar

shahriar_shaon wrote a reply+100 XP

4mos ago

Yes, I am using larastan, but I’m extremely confused about my code structure. Will you help me? To review my code.

shahriar_shaon's avatar

shahriar_shaon wrote a reply+100 XP

4mos ago

Yes, you can set a cookie when returning an Inertia.js response. Inertia responses are still just normal HTTP responses from your backend framework, so you set cookies the same way you normally would. Inertia does not provide its own cookie API.

use Inertia\Inertia;
use Illuminate\Support\Facades\Cookie;

public function index()
{
    Cookie::queue('my_cookie', 'some value', 60); // 60 minutes

    return Inertia::render('Dashboard', [
        'example' => 'data',
    ]);
}
shahriar_shaon's avatar

shahriar_shaon wrote a reply+100 XP

4mos ago

The issue happens because the router is creating a new Pinia store instance when you call useUserStore() inside the router guard. This latest instance does not contain the authenticated user, so isAuthorized always shows false.

router/index.js

import { useUserStore } from '@/store/user'
import pinia from '@/store'

router.beforeEach((to, from, next) => {
  const userStore = useUserStore(pinia)

  if ((to.name === 'login' || to.name === 'register') && userStore.isAuthorized) {
    return next('/')
  }

  next()
})
shahriar_shaon's avatar

shahriar_shaon started a new conversation+100 XP

4mos ago

I’m extremely confused about my code structure and I’m hoping a senior developer can help me out.

My confusion: I’m using PHPStan at the maximum level, which means I have to write a lot of heavy annotations just to satisfy PHPStan. Also, I’ve never used DTOs before — this is my first project using them — so I’m not even sure if I’m following the correct approach.

What’s troubling me the most is that after validating the data, when I pass it into the DTO, PHPStan keeps giving warnings because of mixed values.

I’m sharing my project’s GitHub link below. If anyone kind-hearted could take a look at my code, point out where I’m going wrong, and guide me toward the proper way to structure things, I would really appreciate it.

github.com/shahriarshaon1993/myfinance